.NET Runtime-Unterstützung für Ausdrucksbaumstrukturen

Es gibt eine umfangreiche Liste von Klassen in .NET Runtime, die mit Ausdrucksbaumstrukturen arbeiten. Die vollständige Liste finden Sie unter System.Linq.Expressions. Anstatt die vollständige Liste aufzuzählen, sehen wir uns an, wie die Runtime-Klassen entwickelt wurden.

Im Sprachentwurf ist ein Ausdruck ein Teil eines Codes, der ausgewertet wird und einen Wert zurückgibt. Ausdrücke können sehr einfach sein: Der konstante Ausdruck 1 gibt den konstanten Wert 1 zurück. Sie sind möglicherweise komplizierter: Der Ausdruck (-B + Math.Sqrt(B*B - 4 * A * C)) / (2 * A) gibt ein Stammverzeichnis für eine quadratische Gleichung zurück (in dem Fall, in dem die Gleichung eine Lösung hat).

System.Linq.Expression und abgeleitete Typen

Eine der Komplexitäten der Arbeit mit Ausdrucksbaumstrukturen ist, dass viele verschiedene Arten von Ausdrücken an vielen Stellen in Programmen gültig sind. Betrachten Sie einen Zuweisungsausdruck. Die rechte Seite einer Zuweisung kann ein konstanter Wert, eine Variable, ein Methodenaufrufausdruck oder anderes sein. Die Sprachflexibilität bedeutet, dass Sie viele unterschiedliche Ausdruckstypen an beliebigen Stellen in den Knoten einer Struktur erhalten können, wenn Sie eine Ausdrucksbaumstruktur durchlaufen. Darum ist es am einfachsten, wenn Sie mit dem Basisausdruckstyp arbeiten. Allerdings müssen Sie manchmal mehr wissen. Die Basisausdrucksklasse enthält eine NodeType-Eigenschaft für diesen Zweck. Er gibt einen ExpressionType zurück, der eine Enumeration möglicher Ausdruckstypen ist. Wenn Sie den Typ des Knotens kennen, führen Sie eine Umwandlung in diesen Typ durch, und bestimmte Aktionen, die den Typ des Ausdrucksknotens kennen. Sie können nach bestimmten Knoten suchen, und anschließend mit den bestimmten Eigenschaften dieser Art von Ausdruck arbeiten.

Dieser Code gibt z. B. den Namen einer Variablen für einen Variablenzugriffsausdruck aus. Der folgende Code zeigt die Methode der Überprüfung des Knotentyps, die anschließende Umwandlung in einen Variablenzugriffsausdruck und dann die Überprüfung der Eigenschaften des bestimmten Ausdruckstyps:

Expression<Func<int, int>> addFive = (num) => num + 5;

if (addFive is LambdaExpression lambdaExp)
{
    var parameter = lambdaExp.Parameters[0];  -- first

    Console.WriteLine(parameter.Name);
    Console.WriteLine(parameter.Type);
}

Erstellen von Ausdrucksbaumstrukturen

Die System.Linq.Expression-Klasse enthält außerdem viele statische Methoden zum Erstellen von Ausdrücken. Diese Methoden erstellen mithilfe der Argumente für seine untergeordneten Elemente einen Ausdrucksknoten. Auf diese Weise erstellen Sie einen Ausdruck über seine Endknoten. Dieser Code erstellt z.B. einen Add-Ausdruck:

// Addition is an add expression for "1 + 2"
var one = Expression.Constant(1, typeof(int));
var two = Expression.Constant(2, typeof(int));
var addition = Expression.Add(one, two);

Sie können in diesem einfachen Beispiel erkennen, dass viele Typen bei der Erstellung und beim Arbeiten mit Ausdrucksbaumstrukturen beteiligt sind. Diese Komplexität ist erforderlich, um die Funktionalität des rich-Vokabulars der C#-Sprache bereitzustellen.

Es gibt Ausdrucksknotentypen, die fast alle Elemente der Syntax der C#-Sprache zuordnen. Jeder Typ verfügt über spezielle Methoden für diese Art von Sprachelement. Es ist viel, was Sie sich gleichzeitig merken müssen. Damit Sie sich nicht alles aus dem Gedächtnis rufen müssen, finden Sie hier die Techniken, die Sie zum Arbeiten mit Ausdrucksbaumstrukturen verwenden:

  1. Betrachten Sie die Member des ExpressionType-enum, um mögliche Knoten zu bestimmen, die Sie untersuchen sollten. Diese Liste ist hilfreich, wenn Sie eine Ausdrucksbaumstruktur durchlaufen und verstehen möchten.
  2. Betrachten Sie die statischen Member der Expression-Klasse, um einen Ausdruck zu erstellen. Diese Methoden können jeden Ausdruckstyp aus einer Reihe von untergeordneten Knoten erstellen.
  3. Sehen Sie sich die ExpressionVisitor-Klasse an, um eine geänderte Ausdrucksbaumstruktur zu erstellen.

Sie finden mehr, wenn Sie sich jeden dieser drei Bereiche ansehen. Unweigerlich stellen Sie fest, was Sie benötigen, wenn Sie mit einem dieser drei Schritte starten.