MemberExpression: переменная InvalidOperationExpression 'x', на которую ссылается область действия '', но она не определена
Я использую 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 ответ
Вы создаете разные параметры, которые называются "х" несколько раз. Если вы используете один 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();
В основном выражения параметров не совпадают по имени - везде нужно использовать одно и то же. Это немного больно, но мы идем...