MemberExpression: la variable InvalidOperationExpression 'x' hace referencia desde el alcance '', pero no está definida

c# expression-trees linq

Pregunta

Estoy usando System.Linq.Expressions

Estaba intentando construir una LambdaExpression simple que incluye una expresión de miembro . Si creo MemberExpression explícitamente con la API System.Linq.Expressions (por ejemplo, MakeMemberAccess ), obtendré el error "Variable de InvalidOperationExpression 'referenciada desde el alcance' ', pero no se define" cuando llamo Compile () en el LambdaExpression.

Por ejemplo, este es mi código.

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

expresión2 y expresión3 lanzan una excepción cuando se llama al método Compile (), pero expresión1 no; expresión1 funciona. ¿Por qué es esto? ¿Cómo creo una Expresión de Miembro como en las expresiones 2, 3 y hago que funcionen (no lance una excepción) cuando llamo Compilar ()?

Gracias

Respuesta aceptada

Estás creando diferentes parámetros llamados "x" varias veces. Si utiliza una única ParameterExpression , todo debería funcionar bien.

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();

Básicamente, las expresiones de los parámetros no coinciden con el nombre, debes usar la misma en todas partes. Es un poco molesto, pero ahí vamos ...




Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué