Test classes
public class Foo
{
public Bar Bar { get; set; }
}
public class Bar
{
public string Baz { get; set; }
}
public class BindFoo
{
public string BarBaz { get; set; }
}
片段
Expression<Func<Foo, object>> baz = x => x.Bar.Baz;
var param = Expression.Parameter(typeof(Foo), "x");
var bindings = typeof(BindFoo)
.GetProperties()
.Select(x => Expression.Bind(x, (MemberExpression)baz.Body))
.OfType<MemberBinding>()
.ToArray();
var expression = Expression.Lambda<Func<Foo, object>>(
Expression.MemberInit(
Expression.New(typeof(BindFoo).GetConstructor(Type.EmptyTypes)),
bindings),
param);
var func = expression.Compile();
在嵌套属性时expression.Compile()
引发"x"未定义错误。如何绑定嵌套属性 Bar.Baz?
上面代码中内置的表达式是x => new BindFoo() {BarBaz = x.Bar.Baz}
,这是我想要的,但我认为x.Bar.Baz
没有正确绑定。
该问题与Bind
和嵌套成员无关,而是与动态创建的 lambda 表达式的参数有关。
参数按实例绑定,而不是按名称绑定。这里
Expression<Func<Foo, object>> baz = x => x.Bar.Baz;
var param = Expression.Parameter(typeof(Foo), "x");
您定义了一个新参数,但随后尝试使用绑定到其自己的参数baz.Body
。
解决方案是使用原始参数
Expression<Func<Foo, object>> baz = x => x.Bar.Baz;
var param = baz.Parameters[0];
或者使用表达式访问者将baz.Parameters[0]
替换为新参数。