Wird der Transformationsvorgang des Lambda-Ausdrucksbaums irgendwo angegeben?

8

Es gibt zwei wichtige Schritte zum Kompilieren einer LINQ-Abfrage in C #. Die erste besteht in der Umwandlung der LINQ-Abfragesyntax in eine Kette von Methodenaufrufen, wie in Abschnitt 7.16 der C # -Sprachenspezifikation beschrieben. Dieser Transformationsprozess ist so detailliert spezifiziert, dass ein Sprachentwickler damit eine ähnliche Abfragesyntax in einer neuen CLR-Sprache implementieren kann.

Der zweite Schritt besteht darin, Lambda-Ausdrücke in Ausdrucksbäume umzuwandeln. Dies geschieht beim Aufruf einer Abfrage-Methode, die IQueryable zurückgibt, aber nicht beim Aufruf einer Methode, die IEnumerable zurückgibt. Ist es jemals spezifiziert, wie diese Transformation stattfindet, vergleichbar mit der Erklärung der Transformation der Abfrage-Syntax?

    
Mason Wheeler 05.11.2014, 02:28
quelle

2 Antworten

5

Die Konstruktion von Ausdrucksbäumen ist eigentlich nicht definiert. Compiler-Entwickler können frei wählen, was sie wollen, vorausgesetzt natürlich, dass das Ausführen des Ausdrucks das gleiche Ergebnis liefert wie das Aufrufen des Lambda.

Dies ist ein Zitat aus der C # -Sprachspezifikation:

6.5.2 Auswertung von anonymen Funktionskonvertierungen in Ausdrucksbaumtypen

Die Umwandlung einer anonymen Funktion in einen Ausdrucksbaumtyp erzeugt einen Ausdrucksbaum (§4.6). Genauer gesagt führt die Auswertung der anonymen Funktionskonvertierung zur Konstruktion einer Objektstruktur, die die Struktur der anonymen Funktion selbst darstellt. Die genaue Struktur des Ausdrucksbaums sowie der genaue Prozess für die Erstellung des Ausdrucksbaums sind in der Implementierung definiert.

Ich habe das Fett am Ende hinzugefügt.

Ich vermute, dass dies absichtlich nicht spezifiziert wurde, um Compiler-Entwicklern die Freiheit zu geben, alle ihnen nützlichen Optimierungen zu implementieren. Eine starre Spezifikation des Ausdrucksbaums würde das verhindern.

    
NSFW 06.11.2014, 09:19
quelle
0
  

Ist es jemals spezifiziert, wie diese Transformation stattfindet, vergleichbar?   zur Erklärung der Transformation der Abfrage Syntax?

Wie NSFW gesagt hat, nein.

Praktisch können diese Ausdrucksbäume von Framework zu Framework wechseln. Ein Beispiel aus dem wirklichen Leben wäre das:

Wir haben expression lambdas verwendet, um die Eigenschafteninformationen über Ausdrucksbäume zu erhalten.

Wie void DoSomething<P, K>(P model, Expression<Func<P, K> propertySelector) und die Verwendung DoSomething(model, m => m.Property)

Die eigentliche Immobilienabfrage wurde innerhalb von DoSomething durch Reflexion durchgeführt. Das ist sehr klassisch, und Varianten dieses Codes existieren über das Internet.

Nun, das ist cool, es hat in .NET 4.0 gut funktioniert. Sobald ich jedoch 4.5 getestet habe, explodierte es vollständig, da sich der zugrunde liegende Ausdrucksbaum geändert hat.

Sie können sicher sein, dass Roslyn viele neue "Bugs" einführen wird, in dem Sinne, dass einige Client-Codes auf der Darstellung von Lambdas in Ausdrucksbäumen basieren (wenn Sie darauf bestehen, dass Visitor class minimiert) die Chancen zu brechen).

Sicherzustellen, dass die Ausdrucksbäume gleich bleiben, wäre eine große Aufgabe, und sie wäre auch einschränkend (zum Beispiel in Bezug auf die Geschwindigkeit)

    
Erti-Chris Eelmaa 06.11.2014 10:29
quelle