用对象初始化器创建一个实例的表达式 [英] Expression to create an instance with object initializer

查看:130
本文介绍了用对象初始化器创建一个实例的表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  //我的类
public class MyObject {
public bool DisplayValue {get;组;
}

//我的lambda:
var lambda =(Func< bool,MyObject>)
(displayValue => new MyObject {DisplayValue = displayValue} );

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



更新:



我尝试了自己写下以下代码:

  public static Func< bool,dynamic>造物主; 

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 .Compile();
}

但它会引发以下错误:


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


可以帮助我吗?

解决方案

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

 表达式< Func< bool,MyObject>> 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 }

为了验证这实际上是你想要的,你可以调用 ToString()在创建的表达式上。在这种情况下,输出是预期的:

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


Is there any way to create an instance of an object with object initializer with an Expression Tree? I mean create an Expression Tree to build this lambda:

// my class
public class MyObject {
    public bool DisplayValue { get; set; }
}

// my lambda:
var lambda = (Func<bool, MyObject>)
             (displayValue => new MyObject { DisplayValue = displayValue });

How can I create this lambda with an Expression Tree?

UPDATE:

I tryed myself and write following code:

    public static Func<bool, dynamic> 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<bool, dynamic>>(block, displayValueParam)
                .Compile();
    }

But it throws the following error:

Cannot jump to undefined label ''.

Can everybody help me please?

解决方案

To represent object initializers in an Expression, you should use Expression.MemberInit():

Expression<Func<bool, MyObject>> 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<Func<bool, MyObject>>(memberInit, displayValueParam);
}

To verify this actually does what you want, you can call ToString() on the created expression. In this case, the output is as expected:

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

这篇关于用对象初始化器创建一个实例的表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆