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

时间:2014-06-01 18:23:43

标签: c# dynamic reflection expression-trees anonymous-types

我有一个班级

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 /&#34; Func&#34; -delegate,它创建具有动态重映射属性的匿名对象。

感谢任何帮助。

1 个答案:

答案 0 :(得分:7)

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

因此,为了模仿这一点,您还需要创建自己的类型。或者,您可以使用Tuple<T1, T2>等 - 根据您拥有的属性数使用正确的元组类型。