Framework-Typen, die Ausdrucksbaumstrukturen unterstützenFramework Types Supporting Expression Trees

Vorherige – Ausdrucksbaumstrukturen mit ErläuterungPrevious -- Expression Trees Explained

Es gibt eine umfangreiche Liste von Klassen im .NET Core Framework, die mit Ausdrucksbaumstrukturen arbeiten.There is a large list of classes in the .NET Core framework that work with Expression Trees. Hier finden Sie die vollständige Liste.You can see the full list here. Anstatt die vollständige Liste zu durchlaufen, sehen wir uns an, wie die Framework-Klassen entwickelt wurden.Rather than run through the full list, let's understand how the framework classes have been designed.

Im Sprachentwurf ist ein Ausdruck ein Teil eines Codes, der ausgewertet wird und einen Wert zurückgibt.In language design, an expression is a body of code that evaluates and returns a value. Ausdrücke können sehr einfach sein: Der konstante Ausdruck 1 gibt den konstanten Wert 1 zurück.Expressions may be very simple: the constant expression 1 returns the constant value of 1. 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).They may be more complicated: The expression (-B + Math.Sqrt(B*B + 4 * A * C)) / (2 * A) returns one root for a quadratic equation (in the case where the equation has a solution).

Es beginnt alles mit System.Linq.ExpressionIt all starts with System.Linq.Expression

Eine der Komplexitäten der Arbeit mit Ausdrucksbaumstrukturen ist, dass viele verschiedene Arten von Ausdrücken an vielen Stellen in Programmen gültig sind.One of the complexities of working with expression trees is that many different kinds of expressions are valid in many places in programs. Betrachten Sie einen Zuweisungsausdruck.Consider an assignment expression. Die rechte Seite einer Zuweisung kann ein konstanter Wert, eine Variable, ein Methodenaufrufausdruck oder anderes sein.The right hand side of an assignment could be a constant value, a variable, a method call expression, or others. 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.That language flexibility means that you may encounter many different expression types anywhere in the nodes of a tree when you traverse an expression tree. Wenn Sie mit dem Typ des Ausdrucks arbeiten können, ist dies daher der einfachste Weg zum Arbeiten.Therefore, when you can work with the base expression type, that's the simplest way to work. Allerdings müssen Sie manchmal mehr wissen.However, sometimes you need to know more. Die Basisausdrucksklasse enthält eine NodeType-Eigenschaft für diesen Zweck.The base Expression class contains a NodeType property for this purpose. Es gibt einen ExpressionType zurück, der eine Enumeration möglicher Ausdruckstypen ist.It returns an ExpressionType which is an enumeration of possible expression types. Wenn Sie den Typ des Knotens kennen, können Sie es in diesen Typ umwandeln, und bestimmte Aktionen, die den Typ des Ausdrucksknotens kennen, durchführen.Once you know the type of the node, you can cast it to that type, and perform specific actions knowing the type of the expression node. Sie können nach bestimmten Knoten suchen, und anschließend mit den bestimmten Eigenschaften dieser Art von Ausdruck arbeiten.You can search for certain node types, and then work with the specific properties of that kind of expression.

Dieser Code wird z.B. den Namen einer Variablen für einen Variablenzugriff des Ausdrucks ausgeben.For example, this code will print the name of a variable for a variable access expression. Ich habe den Knotentyp überprüft, ihn anschließend in einen Variablenzugriff des Ausdrucks umgewandelt und die Eigenschaften des bestimmten Ausdruckstyps überprüft:I've followed the practice of checking the node type, then casting to a variable access expression and then checking the properties of the specific expression type:

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

if (addFive.NodeType == ExpressionType.Lambda)
{
    var lambdaExp = (LambdaExpression)addFive;

    var parameter = lambdaExp.Parameters.First();

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

Erstellen von AusdrucksbaumstrukturenCreating Expression Trees

Die System.Linq.Expression-Klasse enthält außerdem viele statische Methoden zum Erstellen von Ausdrücken.The System.Linq.Expression class also contains many static methods to create expressions. Diese Methoden erstellen mithilfe der Argumente für seine untergeordneten Elemente einen Ausdrucksknoten.These methods create an expression node using the arguments supplied for its children. Auf diese Weise erstellen Sie einen Ausdruck über seine Endknoten.In this way, you build an expression up from its leaf nodes. Dieser Code erstellt z.B. einen Add-Ausdruck:For example, this code builds an Add expression:

// 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.You can see from this simple example that many types are involved in creating and working with expression trees. Diese Komplexität ist erforderlich, um die Funktionalität des rich-Vokabulars der C#-Sprache bereitzustellen.That complexity is necessary to provide the capabilities of the rich vocabulary provided by the C# language.

Es gibt Ausdrucksknotentypen, die fast alle Elemente der Syntax der C#-Sprache zuordnen.There are Expression node types that map to almost all of the syntax elements of the C# language. Jeder Typ verfügt über spezielle Methoden für diese Art von Sprachelement.Each type has specific methods for that type of language element. Es ist viel, was Sie sich gleichzeitig merken müssen.It's a lot to keep in your head at one time. Anstatt sich alles zu merken, finden Sie hier die Techniken, die ich zum Arbeiten mit Ausdrucksbaumstrukturen verwende:Rather than try to memorize everything, here are the techniques I use to work with Expression trees:

  1. Betrachten Sie die Member des ExpressionType-enum, um mögliche Knoten zu bestimmen, die Sie untersuchen sollten.Look at the members of the ExpressionType enum to determine possible nodes you should be examining. Dies ist wirklich hilfreich, wenn Sie eine Ausdrucksbaumstruktur durchlaufen und verstehen möchten.This really helps when you want to traverse and understand an expression tree.
  2. Betrachten Sie die statischen Member der Expression-Klasse, um einen Ausdruck zu erstellen.Look at the static members of the Expression class to build an expression. Diese Methoden können jeden Ausdruckstyp aus einer Reihe von untergeordneten Knoten erstellen.Those methods can build any expression type from a set of its child nodes.
  3. Sehen Sie sich die ExpressionVisitor-Klasse an, um eine geänderte Ausdrucksbaumstruktur zu erstellen.Look at the ExpressionVisitor class to build a modified expression tree.

Sie werden mehr finden, wenn Sie sich jeden dieser drei Bereiche ansehen.You'll find more as you look at each of those three areas. Unweigerlich, werden Sie feststellen, was Sie benötigen, wenn Sie mit einem dieser drei Schritte starten.Invariably, you will find what you need when you start with one of those three steps.

Weiter -- Ausführen von AusdrucksbaumstrukturenNext -- Executing Expression Trees