MemberExpression: переменная InvalidOperationExpression 'x' ссылка из области действия '', но она не определена - PullRequest
8 голосов
/ 24 мая 2011

Я использую System.Linq.Expressions

Я пытался создать простое LambdaExpression , которое включает MemberExpression .Если я явно создаю MemberExpression с помощью API-интерфейса System.Linq.Expressions (например, MakeMemberAccess ), я получу ошибку «Переменная InvalidOperationExpression« x », на которую ссылаются из области действия», но когда она не определена »вызовите Compile () для LambdaExpression.

Например, это мой код

Expression<Func<Customer, string>> expression1, expression2, expression3;
Func<Customer, string> fn;
expression1 = (x) => x.Title;
fn = expression1.Compile();//works
fn(c);
MemberExpression m;
m = Expression.MakeMemberAccess(
Expression.Parameter(typeof(Customer), "x"), typeof(Customer).GetProperty("Title"));
expression2 = Expression.Lambda<Func<Customer, string>>(m,
    Expression.Parameter(typeof(Customer), "x"));

m = Expression.Property(Expression.Parameter(typeof(Customer),"x"), "Title");
expression3 = Expression.Lambda<Func<Customer, string>>(m,
    Expression.Parameter(typeof(Customer), "x"));

fn = expression3.Compile();//InvalidOperationExpression variable 'x' referenced from scope '', but it is not defined
fn = expression2.Compile();//InvalidOperationExpression variable 'x' referenced from scope '', but it is not defined

expression2 и expression3 выдают исключение при вызове метода Compile (), но expression1 этого не делает;выражение1 работает.Почему это?Как мне создать MemberExpression, как в выражениях 2, 3, и заставить их работать (не выбрасывать исключение), когда я вызываю Compile ()?

Спасибо

1 Ответ

15 голосов
/ 24 мая 2011

Вы создаете различные параметры, которые называются "x" несколько раз.Если вы используете один ParameterExpression, все должно работать нормально.

ParameterExpression p = Expression.Parameter(typeof(Customer), "x");
MemberExpression m = Expression.MakeMemberAccess(p, 
    typeof(Customer).GetProperty("Title"));
expression2 = Expression.Lambda<Func<Customer, string>>(m, p);

m = Expression.Property(p, "Title");
expression3 = Expression.Lambda<Func<Customer, string>>(m, p);

fn = expression3.Compile();
fn = expression2.Compile();

В основном выражения параметров не совпадают по именам - вы должны использовать то же самое вездеЭто немного больно, но мы идем ...

...