【问题标题】:Pass value generated in Expression tree to sub-tree将表达式树中生成的值传递给子树
【发布时间】:2013-08-12 10:34:22
【问题描述】:

如果我在外部表达式树中声明:

var creatorExpression = Expression.New(targetType);

我想在一个或子表达式中使用它,为新实例的属性赋值,例如:

var assignmentExpression = Expression.Assign(targetMemberExpression, valueExpression);

我该怎么办?

目前我将所有赋值表达式放入Expression.Block,但我看不到将实例传递到此块的方法。它需要 ParameterExpressions 但我没有传入实例;我传入的是需要构造的类型。

【问题讨论】:

    标签: c# expression-trees


    【解决方案1】:

    类似:

    Type targetType = typeof(MyClass);
    
    var obj = Expression.Variable(targetType);
    
    var creatorExpression = Expression.New(targetType);
    var assign = Expression.Assign(obj, creatorExpression);
    
    var prop = Expression.PropertyOrField(obj, "MyProp1");
    var value = Expression.Constant(5);
    var member = Expression.Assign(prop, value);
    
    var block = Expression.Block(new[] { obj }, creatorExpression, assign, member);
    

    你必须记住Expression.New(targetType) 是new something(),所以如果你直接在其他地方使用它,你每次都在重新创建对象。你不想:

    new MyClass().MyProp1 = 5;
    new MyClass().MyProp2 = 6;
    

    你想要的

    var obj = new MyClass(); // assign + creatorExpression 
    obj.MyProp1 = 5; // member + prop + value
    obj.MyProp2 = 6; // not in the example
    

    如果您知道您正在访问的属性/字段是属性或字段,您可以使用Expression.Property 或Expression.Field。两者都接受string作为属性/字段名称或PropertyInfo/MethodInfo,可以通过反射获得。

    如果您有一个执行分配的函数并返回一个带有分配的块,您可以将obj 表达式传递给它,例如:

    BlockExpression MakeSomeAssignments(ParameterExpression obj, Expression value1, int value2)
    {
        var prop1e = Expression.PropertyOrField(obj, "MyProp1");
        var member1e = Expression.Assign(prop1e, value1e);
    
        var prop2e = Expression.PropertyOrField(obj, "MyProp2");
        var value2e = Expression.Constant(value2);
        var member2e = Expression.Assign(prop2e, value2e);
    
        return new Expression.Block(member1e, member2e);
    }
    

    【讨论】:

    • 优秀。谢谢。它将新实例分配给我缺少的变量。许多通过文档,我仍然错过了Expression.Variable 方法。非常感谢
    猜你喜欢
    • 1970-01-01
    • 2016-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-25
    相关资源
    最近更新 更多