Daten == Code? Ja, aber Code == Daten?

Wenn Sie ein Tool wie Reflector
verwenden, um sich das Kompilat
anzusehen, stellen Sie fest, dass der Compiler
automatisch Methoden erstellt, um
den Code von Lambda Expressions aufzunehmen.
(Tipp: Wenn Sie in Reflector
über den Optionsdialog für die Einstellung
Optimization einen der Werte None
und .NET 1.0 auswählen, dann sehen Sie
den Code in einer beinahe unverfälschten
Form. Bei den anderen Einstellungen
konvertiert Reflector den Code wieder in
einen höheren Sprachdialekt, sodass die
Details der Umsetzung auf niedriger Ebene
nicht sichtbar werden).

Das Beispiel gibt hier natürlich einfach
den Wert False aus, da die Funktion
direkt mit den Parametern 10 und 42 ausgeführt
wird (und 10 eben nicht größer 42
ist). Zum Vergleich nun folgende Zeilen:

Expression> expression =
(x, y) => x > y;
Console.WriteLine(expression.ToString( ));

Die Ausgabe des Programms ist in diesem
Fall (x, y) => (x > y) also der Ausdruck
selbst. Es ist nicht möglich, die Funktion,
die in der Expression abgelegt worden ist,
unmittelbar auszuführen. Dazu müsste
die Funktion zunächst kompiliert werden.
Es ist also in diesem Fall tatsächlich
Code in Daten konvertiert worden, also
in ein Format, das nun zur Laufzeit beliebig
weiter manipuliert werden kann.
Dieses Format wird Expression Tree genannt,
wohl wegen der tief verzweigten
hierarchischen Form, die eine Darstellung
des Ausdrucks in der Lambda Expression
oft nimmt, wenn diese ein wenig komplizierter
ist als unser Beispiel.

Synthetische Bäume

Nachdem deutlich wurde, in welcher Form
und mit welchen Einschränkungen die
Speicherung von Code als Daten in C# 3.0
möglich ist, bleibt natürlich die Frage nach
dem Zweck. Es gibt zwei wichtige Dinge,
die mit Expression Trees möglich werden:

  1. Expression Trees können mithilfe von
    Code analysiert werden, z.B. um den
    darin gespeicherten Ausdruck zu anderen
    Zwecken als ursprünglich vorgesehen
    zu verwenden, oder ihn etwa
    in andere Ausgabeformate umzuwandeln,
    z.B. der Verständlichkeit halber.
    Die Analyse von Expression Trees wird
    im Rahmen des LINQ-Projekts an
    vielen Stellen eingesetzt, wodurch die
    Verwendung der Spracherweiterungen
    von LINQ und von Hilfsmethoden wie
    Select oder Where mit den unterschiedlichsten
    Backends möglich wird. LINQ
    to SQL
    z.B. „übersetzt“ Ausdrücke, die
    ein Programmierer im Code als Abfragen
    verwendet, auf dem Weg über Expression
    Trees in SQL-Code.
  2. Die Ausdrücke, die in Expression Trees
    gespeichert werden, können dynamisch
    erzeugt werden. Wie schon aus Punkt 1
    hervorgeht, verwendet LINQ Expression
    Trees
    für seine Abfragen. Somit ist es
    also möglich, dynamisch im Code Abfragen
    zu erzeugen, die durch LINQ interpretiert
    und gegen verschiedene von
    LINQ unterstützte Backends, wie etwa
    SQL Server oder XML-Datenquellen,
    ausgeführt werden können. Wenn Sie
    selbst schon einmal Datenbankanwendungen
    geschrieben haben, kennen Sie
    die Versuchung, SQL-Abfragen im Code
    mithilfe von Strings „zusammenzubauen“.
    Sie wissen aber ebenfalls, dass das
    aus Gründen der Kompatibilität, der
    Stabilität und der Sicherheit keine gute
    Idee ist. Die Erzeugung dynamischer
    Expression Trees bietet eine Alternative,
    die keine dieser Nachteile hat.

Listing 1 enthält ein Beispielprogramm, in
dem der Expression Tree, der schon in vorherigen
Beispielen erzeugt wurde, dieses
Mal dynamisch aufgebaut wird:

Listing 1

var xParameter = Expression.Parameter(typeof(int),
"x");
var yParameter = Expression.Parameter(typeof(int),
"y");
var expressionBody = Expression.
GreaterThan(xParameter, yParameter);
var expression =
Expression.Lambda>(expressionBody, xParameter, yParameter);
Console.WriteLine(expression.ToString( ));
var function = expression.Compile( );
Console.WriteLine(function(10, 42));

Es wird deutlich, dass es zu diesem Zweck eine Reihe
von Hilfsmethoden gibt, die die einzelnen
Bestandteile anhand einiger Parameter
zurückliefern. Damit wird die Konstruktion
auch von komplexen Ausdrücken aus
dem Code heraus recht einfach. …

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.