MemberExpression: InvalidOperationExpression-Variable 'x', auf die vom Bereich '' 'verwiesen wird, ist jedoch nicht definiert

c# expression-trees linq

Frage

Ich verwende System.Linq.Expressions

Ich habe versucht, eine einfache LambdaExpression zu erstellen , die eine MemberExpression enthält . Wenn ich die MemberExpression explizit mit der System.Linq.Expressions-API (zB MakeMemberAccess ) erstelle, erhalte ich den Fehler "InvalidOperationExpression-Variable 'x' referenziert von Scope '', aber ist nicht definiert", wenn ich Compile () aufrufe LambdaExpression.

Zum Beispiel ist dies mein 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 und expression3 lösen eine Exception aus, wenn die Compile () -Methode aufgerufen wird, expression1 jedoch nicht; ausdruck1 funktioniert. Warum ist das? Wie erstelle ich eine MemberExpression wie in den Ausdrücken 2, 3 und bringe sie dazu, zu arbeiten (keine Ausnahme auszulösen), wenn ich Compile () aufruft?

Vielen Dank

Akzeptierte Antwort

Sie erstellen verschiedene Parameter, die mehrmals "x" genannt werden. Wenn Sie einen einzelnen ParameterExpression , sollte alles gut funktionieren.

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

Im Grunde werden Parameterausdrücke nicht mit dem Namen verglichen - Sie müssen den gleichen überall verwenden. Es ist ein bisschen Schmerz, aber da gehen wir ...



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow