所以我最近一直在玩动态构建表达式树,并遇到了这种方法,这看起来有点奇怪。起初,在经常按照
的代码编写代码后,我认为“哦,这正是我需要的”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
的实例?我找不到任何使用此方法的示例。
答案 0 :(得分: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
对哪些内容有用。