Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Ausdrucksstrukturen stellen Code in einer strukturähnlichen Datenstruktur dar, wobei jeder Knoten ein Ausdruck ist, z. B. ein Methodenaufruf oder ein binärer Vorgang, z x < y
. B. .
Wenn Sie LINQ verwendet haben, haben Sie Erfahrung mit einer umfangreichen Bibliothek, in der die Func
Typen Teil des API-Satzes sind. (Wenn Sie mit LINQ nicht vertraut sind, sollten Sie wahrscheinlich das LINQ-Lernprogramm und den Artikel zu Lambda-Ausdrücken vor diesem Thema lesen.) Ausdrucksstrukturen bieten eine umfassendere Interaktion mit den Argumenten, die Funktionen sind.
Sie schreiben Funktionsargumente, in der Regel mithilfe von Lambda-Ausdrücken, wenn Sie LINQ-Abfragen erstellen. In einer typischen LINQ-Abfrage werden diese Funktionsargumente in einen Delegaten transformiert, den der Compiler erstellt.
Sie schreiben bereits Code, der Ausdrucksstrukturen verwendet. Die LINQ-APIs von Entity Framework akzeptieren Ausdrucksstrukturen als Argumente für das LINQ-Abfrageausdrucksmuster. Dadurch kann Entity Framework die in C# geschriebene Abfrage in SQL übersetzen, die im Datenbankmodul ausgeführt wird. Ein weiteres Beispiel ist Moq, ein beliebtes Modellframework für .NET.
Wenn Sie eine umfangreichere Interaktion haben möchten, müssen Sie Ausdrucksstrukturen verwenden. Ausdrucksstrukturen stellen Code als Struktur dar, die Sie untersuchen, ändern oder ausführen. Mit diesen Tools können Sie Code während der Laufzeit bearbeiten. Sie schreiben Code, der ausgeführte Algorithmen untersucht oder neue Funktionen eingibt. In komplexeren Szenarien ändern Sie ausgeführte Algorithmen und übersetzen sogar C#-Ausdrücke in ein anderes Formular für die Ausführung in einer anderen Umgebung.
Sie kompilieren und ausführen Code, der durch Ausdrucksstrukturen dargestellt wird. Das Erstellen und Ausführen von Ausdrucksstrukturen ermöglicht die dynamische Änderung von ausführbarem Code, die Ausführung von LINQ-Abfragen in verschiedenen Datenbanken und die Erstellung dynamischer Abfragen. Weitere Informationen zu Ausdrucksstrukturen in LINQ finden Sie unter Verwenden von Ausdrucksstrukturen zum Erstellen dynamischer Abfragen.
Ausdrucksstrukturen werden auch in der dynamischen Sprachlaufzeit (DYNAMIC Language Runtime, DLR) verwendet, um interoperabilität zwischen dynamischen Sprachen und .NET bereitzustellen und Compilerautoren die Ausgabe von Ausdrucksstrukturen anstelle von Microsoft-Zwischensprache (CIL) zu ermöglichen. Weitere Informationen zur DLR finden Sie unter Übersicht über die Dynamic Language Runtime.
Sie können mit dem C#- oder Visual Basic-Compiler eine Ausdrucksstruktur für Sie erstellen, die auf einem anonymen Lambda-Ausdruck basiert, oder Sie können Ausdrucksstrukturen manuell mithilfe des System.Linq.Expressions Namespace erstellen.
Wenn einem Lambda-Ausdruck eine Variable vom Typ Expression<TDelegate>zugewiesen ist, gibt der Compiler Code aus, um eine Ausdrucksstruktur zu erstellen, die den Lambda-Ausdruck darstellt.
Die folgenden Codebeispiele veranschaulichen, wie der C#-Compiler eine Ausdrucksstruktur erstellt, die den Lambda-Ausdruck num => num < 5
darstellt.
Expression<Func<int, bool>> lambda = num => num < 5;
Sie erstellen Ausdrucksstrukturen in Ihrem Code. Sie erstellen die Struktur, indem Sie jeden Knoten erstellen und die Knoten an eine Struktur anfügen. Sie erfahren, wie Sie Ausdrücke im Artikel zum Erstellen von Ausdrucksstrukturen erstellen.
Ausdrucksbäume sind unveränderlich. Wenn Sie eine Ausdrucksstruktur ändern möchten, müssen Sie eine neue Ausdrucksstruktur erstellen, indem Sie die vorhandene Struktur kopieren und Knoten ersetzen. Sie verwenden einen Ausdrucksstrukturbesucher, um die vorhandene Ausdrucksstruktur zu durchlaufen. Weitere Informationen finden Sie im Artikel zum Übersetzen von Ausdrucksstrukturen.
Nachdem Sie eine Ausdrucksstruktur erstellt haben, führen Sie den code aus, der durch die Ausdrucksstruktur dargestellt wird.
Einschränkungen
Der C#-Compiler generiert Ausdrucksstrukturen nur aus Ausdrucks-Lambdas (oder einzeiligen Lambdas). Es kann keine Lambda-Anweisung (oder mehrzeilige Lambdas) analysiert werden. Weitere Informationen zu Lambda-Ausdrücken in C# finden Sie unter Lambda-Ausdrücke.
Es gibt einige neuere C#-Sprachelemente, die nicht gut in Ausdrucksstrukturen übersetzt werden. Ausdrucksstrukturen können keine Ausdrücke oder async
Lambda-Ausdrücke enthaltenawait
. Viele der in C# 6 und höher hinzugefügten Features werden nicht genau wie in Ausdrucksstrukturen geschrieben angezeigt. Stattdessen werden neuere Features in Ausdrucksstrukturen in der entsprechenden, früheren Syntax verfügbar gemacht, sofern möglich. Andere Konstrukte sind nicht verfügbar. Das bedeutet, dass Code, der Ausdrucksstrukturen interpretiert, bei der neue Sprachfeatures eingeführt werden, identisch ist. Auch bei diesen Einschränkungen können Ausdrucksstrukturen jedoch dynamische Algorithmen erstellen, die auf das Interpretieren und Ändern von Code basieren, der als Datenstruktur dargestellt wird. Es ermöglicht umfangreiche Bibliotheken wie Entity Framework, ihre Aufgaben zu erreichen.
Ausdrucksstrukturen unterstützen keine neuen Ausdrucksknotentypen. Es wäre eine bahnbrechende Änderung für alle Bibliotheken, die Ausdrucksstrukturen interpretieren, um neue Knotentypen einzuführen. Die folgende Liste enthält die meisten C#-Sprachelemente, die nicht verwendet werden können:
- Bedingte Methoden , die aus der Ausgabe entfernt wurden
-
base
Zugang - Methodengruppenausdrücke, einschließlich Adresse (
&
) einer Methodengruppe und anonyme Methodenausdrücke - Verweise auf lokale Funktionen
- Aussagen, einschließlich Zuweisung (
=
) und Ausdrucksausdrücke - Partielle Methoden mit nur einer definierenden Deklaration
- Unsichere Zeigervorgänge
-
dynamic
Transaktionen -
Zusammenfügen von Operatoren mit
null
oderdefault
literal links, Null-Koalierungszuordnung und dem Null-Verteilungsoperator (?.
) - Mehrdimensionale Arrayinitialisierer, indizierte Eigenschaften und Wörterbuchinitialisierer
- Sammlungsausdrücke
-
throw
Ausdrücke - Zugreifen auf
static virtual
Elemente oderabstract
Schnittstellen - Lambda-Ausdrücke mit Attributen
- Interpolierte Zeichenfolgen
- UTF-8-Zeichenfolgenkonvertierungen oder UTF-8-Zeichenfolgenliterale
- Methodenaufrufe mit variablen Argumenten, benannten Argumenten oder optionalen Argumenten
- Ausdrücke mit System.Index oder System.Range, Index "from end" () (
^
) Operatoren oder Bereichsausdrücke (..
) -
async
Lambda-Ausdrücke oderawait
Ausdrücke, einschließlichawait foreach
undawait using
-
Tupelliterale, Tupelkonvertierungen, Tupel
==
oderwith
!=
Ausdrücke -
Verwirft (
_
), Destrukturierungszuweisung, Mustervergleichsoperatoris
oder den Musterabgleichsausdruckswitch
- COM-Aufruf ohne
ref
Angabe der Argumente -
ref
,in
oderout
Parameter,ref
Rückgabewerte,out
Argumente oder beliebige Werte vomref struct
Typ