16

所以我最近一直在玩动态构建表达式树,遇到了这种方法,这似乎有点奇怪。起初我想“哦,这正是我所需要的”在不断地按照

var left = member is FieldInfo ? Expression.Field(instance, (FieldInfo)member) : Expression.Property(instance, (PropertyInfo)member);
var right = ...
var assign = Expression.Assign(left, right);

是的,我知道有Expression.PropertyOrField()电话,但它确实往返反射以按名称查找成员,因为我通常已经有MemberInfo实例。

所以无论如何,我认为Expression.Bind()这对我有用,但它做了一些我不太了解的事情。给定以下代码:

void Main()
{
    var m = typeof(Foo).GetField("Bar");
    Expression.Bind(m, Expression.Constant("")).Dump();
}

public class Foo
{
    public string Bar;
}

它产生MemberAssignment表达式Bar = ""。但是没有实例,也没有静态引用。我将如何将此表达式应用于 的实例Foo?我找不到任何使用这种方法的例子。

4

1 回答 1

15

对象初始化表达式

假设你有:

public class Foo
{
    public int Property { get; set; }
}

然后你可以这样做:

var parameter = Expression.Parameter(typeof(int), "i");
var newExpr = Expression.New(typeof(Foo));
var bindExprs = new[]
    {
        Expression.Bind(typeof(Foo).GetProperty("Property"), parameter)
        // You can bind more properties here if you like.
    };

var body = Expression.MemberInit(newExpr, bindExprs);
var lambda = Expression.Lambda<Func<int, Foo>>(body, parameter);

这类似于:

i => new Foo { Property = i } 

老的:

我无法帮助您解决您决心解决的“性能问题”(使用 Expression.PropertyOrField 真的会在您的应用程序中引入瓶颈吗?我有点怀疑。您应该在过早优化之前确定这一点)编辑:道歉错误地假设这是一个性能优化,并且正如您自己发现的那样,Expression.MakeMemberAccess 是您所需要的),但我可以告诉您什么Expression.Bind是有用的。

于 2013-03-08T16:09:12.573 回答