2009-08-21 5 views

Antwort

50

Sie müssen das Lambda auf einen anderen Typ zuweisen:

// Gives you a delegate: 
Func<int, int> f = x => x * 2; 
// Gives you an expression tree: 
Expression<Func<int, int>> g = x => x * 2; 

Das gleiche gilt für Methodenargumente geht. Sobald Sie jedoch einen solchen Lambda-Ausdruck einem Func<>-Typ zugewiesen haben, können Sie die Ausdrucksbaumstruktur nicht mehr abrufen.

+3

Delegierter ist ein besserer Begriff als Lambda, im ersten Fall. Beides sind Lambda-Ausdrücke, wobei einer implizit in einen anonymen Delegaten, ein anderer in einen Ausdrucksbaum konvertiert wird. – nawfal

+0

@nawfal * 'f' * ist ein Delegierter. Aber 'x => x * 2 'ist ein Lambda-Ausdruck (wie du selbst bemerkt hast). Dein Kommentar deutet an, dass ich etwas anderes gesagt habe, aber ich habe es wirklich nicht getan. –

+1

Sie sagten, der zweite Ausdruck gibt Ihnen einen Ausdrucksbaum. Analog dazu sollte der erste Lambda-Ausdruck * Ihnen einen Delegierten * geben, nicht einen * Lambda * - was Ihr erster Kommentar ist. Nicht pingelig, nur erwähnen, damit es in Zukunft jemandem hilft. – nawfal

10

Konrads Antwort ist exakt. Sie müssen den Lambda-Ausdruck Expression<Func<...>> zuweisen, damit der Compiler den Ausdrucksbaum generiert. Wenn Sie einen Lambda als Func<...>, Action<...> oder einen anderen Delegattyp erhalten, ist alles, was Sie haben, eine Reihe von IL-Anweisungen.

Wenn Sie wirklich ein IL-kompiliertes Lambda zurück in einen Ausdrucksbaum konvertieren müssen, müssten Sie es dekompilieren (z. B. tun, was Lutz Roeders Reflector Tool tut). Ich schlage vor, einen Blick auf die Bibliothek Cecil zu werfen, die erweiterte Unterstützung für die Bearbeitung von ILs bietet und Ihnen eine Menge Zeit sparen könnte.

6

Um Konrads Antwort zu erweitern und Pierre zu korrigieren, können Sie immer noch einen Ausdruck aus einem IL-kompilierten Lambda generieren, obwohl es nicht besonders elegant ist. Augusting Konrads Beispiel:

// Gives you a lambda: 
Func<int, int> f = x => x * 2; 

// Gives you an expression tree: 
Expression<Func<int, int>> g = x => f(x); 
+11

Dies ** nicht ** geben Sie den Ausdruck Baum von der ursprünglichen lamda gibt es einen ** neuen ** Ausdruckbaum, der den Delegierten anruft. Nichts mehr. – Aidiakapi

+0

Die Frage ist nicht spezifisch dafür, einen * äquivalenten * Ausdruck zu erhalten. Für In-Memory-LINQ bietet dies identische Funktionalität. Natürlich konnte es von keinem LINQ-Provider richtig geparst werden. – joniba