使用对象初始值设定项创建实例的表达式

有没有办法用对象初始化器和表达式树创建对象的实例? 我的意思是创建一个表达式树来构建这个lambda:

// my class public class MyObject { public bool DisplayValue { get; set; } } // my lambda: var lambda = (Func) (displayValue => new MyObject { DisplayValue = displayValue }); 

如何使用表达式树创建此lambda?

更新:

我试着自己编写以下代码:

  public static Func Creator; static void BuildLambda() { var expectedType = typeof(MyObject); var displayValueParam = Expression.Parameter(typeof(bool), "displayValue"); var ctor = Expression.New(expectedType); var local = Expression.Parameter(expectedType, "obj"); var displayValueProperty = Expression.Property(ctor, "DisplayValue"); var returnTarget = Expression.Label(expectedType); var returnExpression = Expression.Return(returnTarget,local, expectedType); var returnLabel = Expression.Label(returnTarget, Expression.Default(expectedType)); var block = Expression.Block( new[] { local }, Expression.Assign(local, ctor), Expression.Assign(displayValueProperty, displayValueParam), Expression.Return(Expression.Label(expectedType), local, expectedType), returnExpression, returnLabel ); Creator = Expression.Lambda<Func>(block, displayValueParam) .Compile(); } 

但它会引发以下错误:

无法跳转到未定义的标签”。

大家能帮帮我吗?

要在Expression中表示对象初始值设定项,您应该使用Expression.MemberInit()

 Expression> BuildLambda() { var createdType = typeof(MyObject); var displayValueParam = Expression.Parameter(typeof(bool), "displayValue"); var ctor = Expression.New(createdType); var displayValueProperty = createdType.GetProperty("DisplayValue"); var displayValueAssignment = Expression.Bind( displayValueProperty, displayValueParam); var memberInit = Expression.MemberInit(ctor, displayValueAssignment); return Expression.Lambda>(memberInit, displayValueParam); } 

要validation这实际上是否符合您的要求,您可以在创建的表达式上调用ToString() 。 在这种情况下,输出符合预期:

 displayValue => new MyObject() {DisplayValue = displayValue} 

最后我找到了答案:

 public static Func Creator; static void BuildLambda() { var expectedType = typeof(MyObject); var displayValueParam = Expression.Parameter(typeof(bool), "displayValue"); var ctor = Expression.New(expectedType); var local = Expression.Parameter(expectedType, "obj"); var displayValueProperty = Expression.Property(local, "DisplayValue"); var returnTarget = Expression.Label(expectedType); var returnExpression = Expression.Return(returnTarget,local, expectedType); var returnLabel = Expression.Label(returnTarget, Expression.Default(expectedType)); var block = Expression.Block( new[] { local }, Expression.Assign(local, ctor), Expression.Assign(displayValueProperty, displayValueParam), /* I forgot to remove this line: * Expression.Return(Expression.Label(expectedType), local, expectedType), * and now it works. * */ returnExpression, returnLabel ); Creator = Expression.Lambda>(block, displayValueParam) .Compile(); } 

更新:

虽然它工作正常,但@svick在他的回答中提供了一个更好更短的方式,我正在寻找: MemberInit 。 请参阅@ svick的回答。