Ausdrucksbaumstrukturen (C#)Expression Trees (C#)

Ausdrucksbaumstrukturen stellen Code in einer baumähnlichen Datenstruktur dar, in denen jeder Knoten ein Ausdruck ist, z. B. ein Methodenaufruf oder eine binäre Operation wie x < y.Expression trees represent code in a tree-like data structure, where each node is an expression, for example, a method call or a binary operation such as x < y.

Sie können Code kompilieren und ausführen, der von Ausdrucksbaumstrukturen dargestellt wird.You can compile and run code represented by expression trees. Dies ermöglicht dynamische Änderungen des ausführbaren Codes, die Ausführung von LINQ-Abfragen in verschiedenen Datenbanken und die Erstellung von dynamischen Abfragen.This enables dynamic modification of executable code, the execution of LINQ queries in various databases, and the creation of dynamic queries. Weitere Informationen zu Ausdrucksbaumstrukturen in LINQ finden Sie unter How to: Use Expression Trees to Build Dynamic Queries (C#) (Vorgehensweise: Verwenden von Ausdrucksbaumstrukturen zum Erstellen von dynamischen Abfragen (C#)).For more information about expression trees in LINQ, see How to: Use Expression Trees to Build Dynamic Queries (C#).

Ausdrucksbaumstrukturen werden auch in der Dynamic Language Runtime (DLR) verwendet, um Interoperabilität zwischen dynamischen Sprachen und dem .NET-Framework zu gewährleisten und ermöglicht Entwicklern von Compilern, Ausdrucksbaumstrukturen anstelle der Microsoft Intermediate Language (MSIL) auszugeben.Expression trees are also used in the dynamic language runtime (DLR) to provide interoperability between dynamic languages and the .NET Framework and to enable compiler writers to emit expression trees instead of Microsoft intermediate language (MSIL). Weitere Informationen zur DLR finden Sie unter Übersicht über die Dynamic Language Runtime.For more information about the DLR, see Dynamic Language Runtime Overview.

Sie können den C#- oder Visual Basic-Compiler zur Erstellung einer Ausdrucksbaumstruktur veranlassen, basierend auf einem anonymen Lambda-Ausdruck oder Sie können Ausdrucksbaumstrukturen durch Verwendung des Namespace System.Linq.Expressions manuell erstellen.You can have the C# or Visual Basic compiler create an expression tree for you based on an anonymous lambda expression, or you can create expression trees manually by using the System.Linq.Expressions namespace.

Erstellen von Ausdrucksbaumstrukturen aus Lambda-AusdrückenCreating Expression Trees from Lambda Expressions

Wenn ein Lambda-Ausdruck einer Variablen vom Typ Expression<TDelegate> zugewiesen ist, gibt der Compiler Code aus, um eine Ausdrucksbaumstruktur zu erstellen, die den Lambda-Ausdruck verkörpert.When a lambda expression is assigned to a variable of type Expression<TDelegate>, the compiler emits code to build an expression tree that represents the lambda expression.

Der C#-Compiler kann Ausdrucksbaumstrukturen nur aus Ausdrucklambdas (oder einzeiligen Lambdas) erstellen.The C# compiler can generate expression trees only from expression lambdas (or single-line lambdas). Es kann keine Anweisungslambdas (oder mehrzeiligen Lambdas) analysieren.It cannot parse statement lambdas (or multi-line lambdas). Weitere Informationen zu Lambdaausdrücken in C# finden Sie unter Lambdaausdrücke.For more information about lambda expressions in C#, see Lambda Expressions.

In den folgenden Codebeispielen wird veranschaulicht, wie Sie C#-Compiler dazu veranlassen, eine Ausdrucksbaumstruktur zu erstellen, die den Lambdaausdruck num => num < 5 verkörpert.The following code examples demonstrate how to have the C# compiler create an expression tree that represents the lambda expression num => num < 5.

Expression<Func<int, bool>> lambda = num => num < 5;  

Erstellen von Ausdrucksbaumstrukturen mit der APICreating Expression Trees by Using the API

Verwenden Sie die Klasse Expression, um Ausdrucksbaumstrukturen mit der API zu erstellen.To create expression trees by using the API, use the Expression class. Diese Klasse enthält statische Factorymethoden, die bestimmte Ausdrucksstruktur-Knotentypen erstellen können, z. B. ParameterExpression, der eine Variable oder einen Parameter darstellt oder MethodCallExpression, der einen Methodenaufruf darstellt.This class contains static factory methods that create expression tree nodes of specific types, for example, ParameterExpression, which represents a variable or parameter, or MethodCallExpression, which represents a method call. ParameterExpression, MethodCallExpression, und die anderen ausdrucksspezifischen Ausdrucksbaumstruktur-Typen werden auch im Namespace System.Linq.Expressions definiert.ParameterExpression, MethodCallExpression, and the other expression-specific types are also defined in the System.Linq.Expressions namespace. Diese Typen werden vom abstrakten Typ Expression abgeleitet.These types derive from the abstract type Expression.

Im folgenden Codebeispiel wird veranschaulicht, wie eine Ausdrucksbaumstruktur erstellt wird, die den Lambdaausdruck num => num < 5 mithilfe der API verkörpert.The following code example demonstrates how to create an expression tree that represents the lambda expression num => num < 5 by using the API.

// Add the following using directive to your code file:  
// using System.Linq.Expressions;  

// Manually build the expression tree for   
// the lambda expression num => num < 5.  
ParameterExpression numParam = Expression.Parameter(typeof(int), "num");  
ConstantExpression five = Expression.Constant(5, typeof(int));  
BinaryExpression numLessThanFive = Expression.LessThan(numParam, five);  
Expression<Func<int, bool>> lambda1 =  
    Expression.Lambda<Func<int, bool>>(  
        numLessThanFive,  
        new ParameterExpression[] { numParam });  

In .NET Framework 4 oder höher unterstützt die Ausdrucksbaumstruktur-API auch Zuweisungen und Ablaufsteuerungsausdrücke wie Schleifen, bedingte Blöcke und try-catch-Blöcke.In .NET Framework 4 or later, the expression trees API also supports assignments and control flow expressions such as loops, conditional blocks, and try-catch blocks. Mithilfe der API können Sie Ausdrucksbaumstrukturen erstellen, die komplexer sind als diejenigen, die von Lambda-Ausdrücken vom C#-Compiler erstellt werden.By using the API, you can create expression trees that are more complex than those that can be created from lambda expressions by the C# compiler. Im folgenden Beispiel wird veranschaulicht, wie eine Ausdrucksbaumstruktur erstellt wird, welche die Fakultät einer Zahl berechnet.The following example demonstrates how to create an expression tree that calculates the factorial of a number.

// Creating a parameter expression.  
ParameterExpression value = Expression.Parameter(typeof(int), "value");  

// Creating an expression to hold a local variable.   
ParameterExpression result = Expression.Parameter(typeof(int), "result");  

// Creating a label to jump to from a loop.  
LabelTarget label = Expression.Label(typeof(int));  

// Creating a method body.  
BlockExpression block = Expression.Block(  
    // Adding a local variable.  
    new[] { result },  
    // Assigning a constant to a local variable: result = 1  
    Expression.Assign(result, Expression.Constant(1)),  
    // Adding a loop.  
        Expression.Loop(  
    // Adding a conditional block into the loop.  
           Expression.IfThenElse(  
    // Condition: value > 1  
               Expression.GreaterThan(value, Expression.Constant(1)),  
    // If true: result *= value --  
               Expression.MultiplyAssign(result,  
                   Expression.PostDecrementAssign(value)),  
    // If false, exit the loop and go to the label.  
               Expression.Break(label, result)  
           ),  
    // Label to jump to.  
       label  
    )  
);  

// Compile and execute an expression tree.  
int factorial = Expression.Lambda<Func<int, int>>(block, value).Compile()(5);  

Console.WriteLine(factorial);  
// Prints 120.  

Weitere Informationen finden Sie unter Generating Dynamic Methods with Expression Trees in Visual Studio 2010 (Generieren dynamischer Methoden mit Ausdrucksbaumstrukturen in Visual Studio 2010). Dieser Artikel gilt auch für höhere Versionen von Visual Studio.For more information, see Generating Dynamic Methods with Expression Trees in Visual Studio 2010, which also applies to later versions of Visual Studio.

Analysieren von AusdrucksbaumstrukturenParsing Expression Trees

Im folgenden Codebeispiel wird veranschaulicht, wie die Ausdrucksbaumstruktur, die den Lambdaausdruck num => num < 5 darstellt, in seine Bestandteile zerlegt werden kann.The following code example demonstrates how the expression tree that represents the lambda expression num => num < 5 can be decomposed into its parts.

// Add the following using directive to your code file:  
// using System.Linq.Expressions;  

// Create an expression tree.  
Expression<Func<int, bool>> exprTree = num => num < 5;  

// Decompose the expression tree.  
ParameterExpression param = (ParameterExpression)exprTree.Parameters[0];  
BinaryExpression operation = (BinaryExpression)exprTree.Body;  
ParameterExpression left = (ParameterExpression)operation.Left;  
ConstantExpression right = (ConstantExpression)operation.Right;  

Console.WriteLine("Decomposed expression: {0} => {1} {2} {3}",  
                  param.Name, left.Name, operation.NodeType, right.Value);  

// This code produces the following output:  

// Decomposed expression: num => num LessThan 5  

Unveränderlichkeit von AusdrucksbaumstrukturenImmutability of Expression Trees

Ausdrucksbaumstrukturen sollten unveränderlich sein.Expression trees should be immutable. Das heißt, wenn Sie eine Ausdrucksbaumstruktur ändern möchten, müssen Sie einen neuen Knoten konstruieren, indem Sie einen vorhandenen Knoten kopieren und die enthaltenen Knoten ersetzen.This means that if you want to modify an expression tree, you must construct a new expression tree by copying the existing one and replacing nodes in it. Sie können einen Ausdrucksbaumstruktur-Besucher verwenden, um die vorhandene Ausdrucksbaumstruktur zu durchlaufen.You can use an expression tree visitor to traverse the existing expression tree. Weitere Informationen finden Sie unter How to: Modify Expression Trees (C#) (Vorgehensweise: Bearbeiten von Ausdrucksbaumstrukturen (C#)).For more information, see How to: Modify Expression Trees (C#).

Kompilieren von AusdrucksbaumstrukturenCompiling Expression Trees

Der Typ Expression<TDelegate> bietet die Methode Compile, welche den durch eine Ausdrucksbaumstruktur dargestellten Code in einen ausführbaren Delegaten kompiliert.The Expression<TDelegate> type provides the Compile method that compiles the code represented by an expression tree into an executable delegate.

Im folgenden Codebeispiel wird veranschaulicht, wie eine Ausdrucksbaumstruktur kompiliert und der daraus resultierende Code ausgeführt wird.The following code example demonstrates how to compile an expression tree and run the resulting code.

// Creating an expression tree.  
Expression<Func<int, bool>> expr = num => num < 5;  

// Compiling the expression tree into a delegate.  
Func<int, bool> result = expr.Compile();  

// Invoking the delegate and writing the result to the console.  
Console.WriteLine(result(4));  

// Prints True.  

// You can also use simplified syntax  
// to compile and run an expression tree.  
// The following line can replace two previous statements.  
Console.WriteLine(expr.Compile()(4));  

// Also prints True.  

Weitere Informationen finden Sie unter How to: Execute Expression Trees (C#) (Vorgehensweise: Ausführen von Ausdrucksbaumstrukturen (C#)).For more information, see How to: Execute Expression Trees (C#).

Siehe auchSee Also

System.Linq.Expressions
Vorgehensweise: Ausführen von Ausdrucksbaumstrukturen (C#)How to: Execute Expression Trees (C#)
How to: Modify Expression Trees (C#) (Vorgehensweise: Bearbeiten von Ausdrucksbaumstrukturen (C#))How to: Modify Expression Trees (C#)
Lambda-AusdrückeLambda Expressions
Übersicht über die Dynamic Language RuntimeDynamic Language Runtime Overview
Programmierkonzepte (C#)Programming Concepts (C#)