如何用表达式树构建匿名对象



我有一个class

public class SomeClass
{
    public int num { get; set; }
    public string str{ get; set; }
}

我需要构造一个lambda表达式,如:(x => new {new_num= x.num, new_str= x.str})

属性列在一些可枚举对象中(这很重要)。我们设List<KeyValuePair<string, string>>

我的代码是:
// Test properties list
var listOfParams = new List<KeyValuePair<string, string>>();
listOfParams.Add(new KeyValuePair<string, string>("new_num","num"));
listOfParams.Add(new KeyValuePair<string, string>("new_str","str"));
// SomeClass as particular test case
var tModelType = typeof(SomeClass); 
ParameterExpression pe = Expression.Parameter(tModelType, "m");
NewExpression ne = Expression.New(typeof(object)); //<-- trying to emulate `new object{}`
List<Expression> lInit = new List<Expression>(); 
PropertyInfo pi;
string sAnonymousProperty;
Type propertyType;
foreach(var paramElem in listOfParams)
{
   pi = tModelType.GetProperty(paramElem.Value);
   propertyType = pi.PropertyType;
   sAnonymousProperty = paramElem.Value;
   Expression bind = ??Expression??  // <-- here I need to build binding expression
   lInit.Add( bind );
}
ListInitExpression lie = Expression.ListInit(ne, lInit);
LambdaExpression leResult = Expression.Lambda(lie, pe);

我不能找出绑定表达式,因为它需要MemberInfo,而匿名对象没有。此外,我不能使用new { new_num = 0, new_str = "" }.GetType()巡视它,因为属性是未知的,并作为一些数组作为参数。


也许我的方法是无效的,有人会建议另一种方法,但主要思想是获得lambda-expression/"Func"-delegate,创建具有动态重映射属性的匿名对象。

方法基本上是无效的,因为没有合适的类型可以引用。就CLR而言,匿名类型只是一种普通类型——编译器只是为您生成类型。(在微软的实现中,它实际上生成了一个泛型类型,它用于每个匿名类型,具有相同的属性名,以相同的顺序使用。)

所以为了模拟这个,你也需要创建你自己的类型。或者,您可以使用Tuple<T1, T2>等-根据您拥有的属性数量使用正确的元组类型。

相关内容

  • 没有找到相关文章

最新更新