LambdaExpression kann nicht mit einem Ausdruck initialisiert werden

c# expression-trees lambda

Frage

Frage ähnlich wie eine von John K. , aber spezifischer und die angenommene Antwort passt nicht zu meinen Bedürfnissen.

Das kompiliert gut:

Expression<Func<object, object>> specificExpression = (object o) => new object();
Expression generalExpression = specificExpression;

Und das tut nicht:

Expression generalExpression = (object o) => new object();

Berichtigter Kompilierfehler:

Cannot convert lambda expression to type 'System.Linq.Expressions.Expression' because it is not a delegate type

Expression<Func<T1,T2>> leitet sich von Expression .

Jetzt habe ich ein Framework mit Methoden, die alle Arten von Ausdrücken akzeptieren, zB Expression . Bei jedem Methodenaufruf gezwungen zu sein, Expression<Func<T1,T2>> explizit auf den entsprechenden Expression<Func<T1,T2>> zu Expression<Func<T1,T2>> ist frustrierend.

Gibt es gute Gründe, warum dieses grundlegende OOP-Verhalten in diesem Fall nicht funktioniert?

Akzeptierte Antwort

Die Konvertierung funktioniert nicht, da der Compiler nicht ableiten kann, welchen bestimmten Ausdruckstyp Sie erstellen möchten. Was, wenn du das getan hast?

Expression generalExpression = (object o) => "foo";

Sollte dies ein Expression<Func<object, string>> ? Was ist mit Expression<Func<object, object>> oder Expression<Func<object, IComparable>> ? Diese Typen wären alle ein gültiger Endtyp für den Ausdrucksbaum, und der Compiler gibt nicht vor, zu wissen, was Sie zu tun versuchen.

Sie müssen den spezifischen Typ durchlaufen, um dem Compiler mitzuteilen, welche Art von Ausdruck Sie erzeugen möchten:

Expression generalExpression = (Expression<Func<object, object>>)
    (object o) => new object();

Sie würden einen ähnlichen Compilerfehler sehen, wenn Sie das versuchten:

Delegate generalDelegate = delegate() { };

Ist das eine Action oder ein ThreadStart oder eine andere Art von ThreadStart , die keine Argumente für die Rückgabe von void zurückgeben?


Beliebte Antwort

Der C # -Compiler wertet den Ausdruck auf die am wenigsten komplexe Form aus, zum Beispiel:

 var x = (object o) => new object();

x sollte ein Func<object, object> , kein Expression<Func<object, object>> . In diesem Fall bestimmt der Compiler, dass der Wert ein Delegat ist, und da Expression keinen Delegaten Expression<Func<>> kann (nur die Expression<Func<>> / Expression<Action> -Typen können), wird der Compilerfehler ausgelöst.

Siehe auch @ Rianas Antwort, da der Ausdruck vom Übersetzer tatsächlich neu geschrieben wurde.



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum