lambda表达式的范围有问题

时间:2014-01-20 11:58:01

标签: c# .net lambda expression-trees

让我们使用我想要调用的方法作为例子:

 MyMethod<MyType, string>(Expression<Func<MyType, string>> expression)

如果我尝试动态构建以下表达式x => x.Name并将其传递给方法,那么一切正常:

var pi = typeof(MyType).GetProperty("Name");
ParameterExpression pe = Expression.Parameter(typeof(MyType), "x");
MemberExpression me = Expression.Property(pe, pi);
var exp = Expression.Lambda(me, pe);

现在让我们假设在完全相同的范围内,我正在尝试使用以下代码构建此表达式x => item.Name,显然项目与输入参数x不同:

var item = new MyType() { Name = "My name" };
var pi = t.GetProperty("Name");
ParameterExpression pe = Expression.Parameter(typeof(MyType), "x");
ParameterExpression pe2 = Expression.Parameter(typeof(MyType), "item");
MemberExpression me = Expression.Property(pe2, pi);
var exp = Expression.Lambda(me, pe);

当我尝试调用MyMethod时,我收到以下错误,可能是因为在调用MyMethod的范围内没有变量“item”(这不是我构建表达式的地方):

variable 'item' of type 'MyType' referenced from scope '', but it is not defined

如何以不会抛出此错误的方式构建此表达式?

2 个答案:

答案 0 :(得分:3)

在lambda的范围内,item位是常量 - 它不是调用的变量参数。

所以以下内容应该更接近:

var item = new MyType() { Name = "My name" };
var pi = t.GetProperty("Name");
ParameterExpression pe = Expression.Parameter(typeof(MyType), "x");
ConstantExpression ce = Expression.Constant(typeof(MyType), item);
MemberExpression me = Expression.Property(ce, pi);
var exp = Expression.Lambda(me, pe);

答案 1 :(得分:2)

字符串"item"与本地变量item没有任何关系。如果您希望构造的lambda表达式捕获局部变量{{}的值1}},然后代替item,您需要Expression.Parameter(typeof(MyType), "item")