gpt4 book ai didi

c# - 将 ExpandoObject 转换为匿名类型

转载 作者:可可西里 更新时间:2023-11-01 08:45:10 26 4
gpt4 key购买 nike

我可以将 ExpandoObject 转换为匿名类型吗?

var anoObj = new { name = "testName", email = "testEmail" };

dynamic expandoObj = new System.Dynamic.ExpandoObject();

// Here I'm populating the expandoObj with same property names/types in anonymoustype(anoObj)

// Now, how to convert this ExpandoObject to anonymoustype ?

var newObj = (typeof(anoObj)expandoObj); // This doesn't work

稍后添加

//这是我的实体

public class Customer
{
#region Public Properties

[ColumnAttribute(Name = "IdColumn")]
public string Id { get; set; }

[ColumnAttribute(Name = "NameColumn")]
public string Name { get; set; }

[ColumnAttribute(Name = "AddressColumn")]
public string Address { get; set; }

[ColumnAttribute(Name = "EmailColumn")]
public string Email { get; set; }

[ColumnAttribute(Name = "MobileColumn")]
public string Mobile { get; set; }

#endregion
}

//------------------------------------------ ----------------------------------------

public class LookupService<TEntitySource>
{
public LookupService ()
{

}

public LookupShowable<TEntitySource, TSelection> Select<TSelection>(Expression<Func<TEntitySource, TSelection>> expression)
{
var lookupShowable = new LookupShowable<TEntitySource, TSelection>();

return lookupShowable;
}
}

public class LookupShowable<TEntitySource,TSelection>
{
public LookupShowable()
{

}

public LookupExecutable<TEntitySource, TSelection, TShow> Show<TShow>(Expression<Func<TEntitySource, TShow>> expression)
{
var lookupExecutable = new LookupExecutable<TEntitySource,TSelection,TShow>();

return lookupExecutable;
}
}

public class LookupExecutable<TEntitySource, TSelection, TShow>
{
public TSelection Execute()
{
// Here I want to create a new instance of TSelection and populate values from database and return it.
}
}

//-------------------------------------------- ----------------------------------------

// This is How I want to call this from front end...
var lookupService = new LookupService<Customer>();
var lookupSelection = lookupService.Select(C => new { C.Id, C.Name, C.Mobile }).Show(C => new { C.Id, C.Name}).Execute();


string sID = lookupSelection.Id;
string sName = lookupSelection.Name;
string sMobile = lookupSelection.Mobile;

不要考虑这个中间部分..它的目的是另一个...

我的问题出在 LookupExecutable 类的 Execute() 方法中。我不知道如何创建 TSelection 类型的新实例并为其赋值。此 TSelection 类型始终是匿名类型..

最佳答案

编辑: 我认为这个问题是 XY problem 的一个主要例子.正确的解决方案不需要关注 ExpandoObject 或匿名类型,如果关注的话很可能是错误的。


你看错了。您不需要创建匿名对象的实例,您需要调用在表达式中传递给您的代码(可能会也可能不会创建匿名对象)。

如果您可以创建TEntitySource 的实例,那就很简单了:Compile()您在 Select() 中获得的 Expression,然后为 TEntitySource 的每个实例调用它。

如果您不能创建 TEntitySource,您仍然可以通过重写 Expression(使用 ExpressionVisitor)来创建它,以便它的输入不是 TEntitySource,而是您拥有的某种类型。但这需要您做一些工作。


原答案:

不,那行不通。这根本不是转换或匿名类型在 C# 中的工作方式。

您不能在任何两种类型之间转换并期望它起作用。您要转换的对象必须是您要转换为的类型,或者两种类型之一需要指定匹配的转换运算符。

目标类型是匿名类型的事实并没有改变任何东西(除了你甚至不能尝试直接转换为匿名类型,因为你不能命名它;你使用的方式 typeof() 是错误的)。

源类型是 dynamic 的事实稍微改变了一些事情。但唯一的原因是对 cast 运算符的搜索是在运行时完成的,而不是在编译时完成的,您甚至可以在运行时创建 cast 运算符(参见 DynamicObject.TryCast() )。但仅此而已,它没有添加任何“神奇”的转换运算符。

如果您使用 “cast by example” 的变体,我能想象的唯一方法就是这样工作和反射(reflection):

public T Convert<T>(ExpandoObject source, T example)
where T : class
{
IDictionary<string, object> dict = source;

var ctor = example.GetType().GetConstructors().Single();

var parameters = ctor.GetParameters();

var parameterValues = parameters.Select(p => dict[p.Name]).ToArray();

return (T)ctor.Invoke(parameterValues);
}

然后你可以像这样使用它:

var expando = new ExpandoObject();
dynamic dynamicExpando = expando;
dynamicExpando.Foo = "SomeString";
dynamicExpando.Bar = 156;
var result = Convert(expando, new { Foo = "", Bar = 1 });

请注意,您实际上不能动态调用 Convert()(通过将其传递给 dynamicExpando),因为这意味着它将返回 dynamic 也是。

关于c# - 将 ExpandoObject 转换为匿名类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10241776/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com