MemberExpression: Variable 'x' InvalidOperationExpression référencée à partir de scope '', mais non définie

c# expression-trees linq

Question

J'utilise System.Linq.Expressions

J'essayais de construire une expression simple LambdaExpression qui inclut une expression MemberExpression . Si je crée explicitement MemberExpression avec l'API System.Linq.Expressions (par exemple, MakeMemberAccess ), le message d' erreur "Variable InvalidOperationExpression 'x' référencée à partir de scope '', n'est pas défini" lorsque j'appelle Compile () le LambdaExpression.

Par exemple, ceci est mon code

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 et expression3 lève une exception lorsque la méthode Compile () est appelée, mais pas l'expression1; expression1 fonctionne. Pourquoi est-ce? Comment créer une expression MemberExpress comme dans les expressions 2, 3 et les faire fonctionner (pas une exception) lorsque j'appelle Compile ()?

Merci

Réponse acceptée

Vous créez plusieurs paramètres appelés "x" plusieurs fois. Si vous utilisez un seul ParameterExpression , tout devrait fonctionner correctement.

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

Fondamentalement, les expressions de paramètre ne correspondent pas par nom - vous devez utiliser le même partout. C'est un peu pénible, mais c'est parti ...




Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi