MemberExpression: variabile InvalidOperationExpression 'x' referenziata dall'ambito '', ma non è definita

c# expression-trees linq

Domanda

Sto usando System.Linq.Expressions

Stavo tentando di creare una semplice LambdaExpression che includesse un membroExpression . Se creo MemberExpression in modo esplicito con l'API System.Linq.Expressions (ad esempio, MakeMemberAccess ), visualizzerò l'errore "Variabile InvalidOperationExpression 'x' referenziato dall'ambito '', ma non è definito" quando chiamo Compile () sul LambdaExpression.

Ad esempio, questo è il mio codice

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 e expression3 generano un'eccezione quando viene chiamato il metodo Compile (), ma expression1 no; expression1 funziona. Perchè è questo? Come posso creare un MemberExpression come nelle espressioni 2, 3 e farli funzionare (non lanciare un'eccezione) quando chiamo Compile ()?

Grazie

Risposta accettata

Stai creando diversi parametri chiamati "x" più volte. Se si utilizza un ParameterExpression , dovrebbe funzionare correttamente.

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

Fondamentalmente le espressioni dei parametri non corrispondono al nome: devi usare lo stesso ovunque. È un po 'un dolore, ma ci siamo ...



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché