Drzewa wyrażeń (C#)Expression Trees (C#)

Drzewa wyrażeń reprezentuje kod w strukturze drzewa danych każdy węzeł w przypadku wyrażenia, na przykład, wywołanie metody lub operację binarną takich jak 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.

Możesz skompilować i uruchomić kod reprezentowany przez drzewa wyrażeń.You can compile and run code represented by expression trees. Umożliwia dynamiczne modyfikacji kodu wykonywalnego, wysyła zapytanie do wykonywania zapytań LINQ w różnych baz danych i tworzenie zapytań dynamicznych.This enables dynamic modification of executable code, the execution of LINQ queries in various databases, and the creation of dynamic queries. Aby uzyskać więcej informacji na temat drzew wyrażeń w składniku LINQ, zobacz porady: użycie drzew wyrażeń do tworzenia zapytań dynamicznych (C#).For more information about expression trees in LINQ, see How to: Use Expression Trees to Build Dynamic Queries (C#).

Drzewa wyrażeń są również używane w środowisku uruchomieniowym języka dynamicznego (DLR), aby zapewnić współdziałanie między językami dynamiczne i .NET Framework i umożliwić autorów kompilatora, aby emitować drzew wyrażeń zamiast język pośredni firmy Microsoft (MSIL).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). Aby uzyskać więcej informacji na temat DLR, zobacz Przegląd środowiska uruchomieniowego języka dynamicznego.For more information about the DLR, see Dynamic Language Runtime Overview.

Masz Utwórz drzewo wyrażeń oparte na wyrażeniu lambda anonimowe lub drzew wyrażeń można tworzyć ręcznie za pomocą kompilatora C# lub Visual Basic System.Linq.Expressions przestrzeni nazw.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.

Tworzenie drzewa wyrażeń z wyrażenia LambdaCreating Expression Trees from Lambda Expressions

Jeśli wyrażenie lambda jest przypisany do zmiennej typu Expression<TDelegate>, kompilator emituje kod, aby utworzyć drzewo wyrażenia, który reprezentuje wyrażenie lambda.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.

Kompilator języka C# można wygenerować drzewa wyrażeń tylko z wyrażenia lambda (lub jednowierszowe wyrażenia lambda).The C# compiler can generate expression trees only from expression lambdas (or single-line lambdas). Nie można go przeanalizować instrukcji lambda (lub wielowierszowego wyrażenia lambda).It cannot parse statement lambdas (or multi-line lambdas). Aby uzyskać więcej informacji na temat wyrażeń lambda w języku C#, zobacz wyrażenia Lambda.For more information about lambda expressions in C#, see Lambda Expressions.

W poniższych przykładach kodu przedstawiają sposób kompilatora C# Utwórz drzewo wyrażeń, który reprezentuje wyrażenie lambda ma num => num < 5.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;  

Tworzenie przy użyciu interfejsu API drzew wyrażeńCreating Expression Trees by Using the API

Aby utworzyć drzewa wyrażeń przy użyciu interfejsu API, użyj Expression klasy.To create expression trees by using the API, use the Expression class. Ta klasa zawiera metody statyczne fabryki, tworzone wyrażenia węzły drzewa określonych typów, na przykład ParameterExpression, reprezentuje zmienna lub parametr, lub MethodCallExpression, który reprezentuje wywołanie metody.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, i inne typy specyficzne dla wyrażenia również są definiowane w System.Linq.Expressions przestrzeni nazw.ParameterExpression, MethodCallExpression, and the other expression-specific types are also defined in the System.Linq.Expressions namespace. Te typy pochodzić od typu abstrakcyjnego Expression.These types derive from the abstract type Expression.

Poniższy przykładowy kod przedstawia sposób tworzenia drzewo wyrażenia, który reprezentuje wyrażenie lambda num => num < 5 przy użyciu interfejsu API.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 });  

W programie .NET Framework 4 lub nowszym API drzewa wyrażenia obsługuje również przydziałów i wyrażeń przepływu sterowania takich jak pętle, bloków warunkowych i try-catch bloków.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. Korzystając z interfejsu API, można utworzyć drzewa wyrażeń, które są bardziej złożone niż te, które mogą być tworzone z wyrażenia lambda za pomocą kompilatora C#.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. W poniższym przykładzie pokazano, jak utworzyć drzewo wyrażenia, który oblicza silnię liczby.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.  

Aby uzyskać więcej informacji, zobacz metody dynamiczne generowanie z drzewa wyrażeń w Visual Studio 2010, która ma zastosowanie również do nowszej wersji programu 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.

Podczas analizowania drzewa wyrażeńParsing Expression Trees

W poniższym przykładzie kodu pokazano, jak wyrażenia drzewa, który reprezentuje wyrażenie lambda num => num < 5 może być rozłożone na jego części.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  

Immutability drzew wyrażeńImmutability of Expression Trees

Drzewa wyrażeń powinno być niezmienialne.Expression trees should be immutable. Oznacza to zmodyfikować drzewo wyrażenia, kopiując istniejący i zastępowanie węzłów w nim należy tworzyć nowe drzewo wyrażenia.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. Obiekt odwiedzający wyrażenie drzewa umożliwia przenoszenie istniejących drzewa wyrażenia.You can use an expression tree visitor to traverse the existing expression tree. Aby uzyskać więcej informacji, zobacz porady: modyfikowanie drzew wyrażeń (C#).For more information, see How to: Modify Expression Trees (C#).

Kompilowanie drzew wyrażeńCompiling Expression Trees

Expression<TDelegate> Typ zapewnia Compile metodę, która kompiluje kod reprezentowany przez drzewo wyrażenia do pliku wykonywalnego delegata.The Expression<TDelegate> type provides the Compile method that compiles the code represented by an expression tree into an executable delegate.

W poniższym przykładzie pokazano, jak skompilować drzewo wyrażeń i uruchomić wynikowy kod.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.  

Aby uzyskać więcej informacji, zobacz porady: wykonywanie drzew wyrażeń (C#).For more information, see How to: Execute Expression Trees (C#).

Zobacz teżSee Also

System.Linq.Expressions
Porady: wykonywanie drzew wyrażeń (C#)How to: Execute Expression Trees (C#)
Porady: modyfikowanie drzew wyrażeń (C#)How to: Modify Expression Trees (C#)
Wyrażenia lambdaLambda Expressions
Przegląd środowiska uruchomieniowego języka dynamicznegoDynamic Language Runtime Overview
Koncepcje programowania (C#)Programming Concepts (C#)