Compartilhar via


Árvores de Expressão

Árvores de expressão representam o nível de linguagem o código do formulário de dados.Os dados são armazenados em uma estrutura em forma de árvore.Cada nó na árvore de expressão representa uma expressão, por exemplo, uma telefonar de método ou uma operação de binário, sistema autônomo x < y.

A ilustração a seguir mostra um exemplo de uma expressão e sua representação na forma de uma árvore de expressão.As diferentes partes da expressão são codificadas para coincidir com o nó de árvore expressão correspondente na árvore de expressão.Também são mostrados os diferentes tipos de nós de árvore de expressão.

O exemplo de código a seguir demonstra como o árvore de expressão que representa o de expressão lambda num => num < 5 (Translation from VPE for Csharp) ou Function(num) num < 5 Pode ser decomposta (Visual Basic) em suas partes.

' Import the following namespace to your project: System.Linq.Expressions

' Create an expression tree.
Dim exprTree As Expression(Of Func(Of Integer, Boolean)) = Function(ByVal num) num < 5

' Decompose the expression tree.
Dim param As ParameterExpression = exprTree.Parameters(0)
Dim operation As BinaryExpression = exprTree.Body
Dim left As ParameterExpression = operation.Left
Dim right As ConstantExpression = operation.Right

MsgBox(String.Format("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

// 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
*/

Criando árvores de expressão

The System.Linq.Expressions namespace Fornece uma API para criação de árvores de expressão manualmente. The Expression classe contém estático métodos de fábrica que crie expressão nós da árvore de tipos específicos, por exemplo um ParameterExpression, que representa uma expressão do parâmetro nomeado, ou um MethodCallExpression, que representa uma telefonar de método. ParameterExpression, MethodCallExpression, e outros tipos de árvore de expressão de expressão específica também estão definidos no System.Linq.Expressions espaço para nome. Esses tipos derivam do tipo abstrato de Expression.

O compilador também pode criar uma árvore de expressão para você.Uma árvore de expressão gerado pelo compilador sempre está enraizada em um nó do tipo Expression<TDelegate>; ou seja, o nó raiz representa uma expressão lambda.

O exemplo de código a seguir demonstra duas formas de criar uma árvore de expressão que representa o de expressão lambda num => num < 5 (Translation from VPE for Csharp) ou Function(num) num < 5 (Visual Basic).

' Import the following namespace to your project: System.Linq.Expressions

' Manually build the expression tree for the lambda expression num => num < 5.
Dim numParam As ParameterExpression = Expression.Parameter(GetType(Integer), "num")
Dim five As ConstantExpression = Expression.Constant(5, GetType(Integer))
Dim numLessThanFive As BinaryExpression = Expression.LessThan(numParam, five)
Dim lambda1 As Expression(Of Func(Of Integer, Boolean)) = _
  Expression.Lambda(Of Func(Of Integer, Boolean))( _
        numLessThanFive, _
        New ParameterExpression() {numParam})

' Let the compiler generate the expression tree for
' the lambda expression num => num < 5.
Dim lambda2 As Expression(Of Func(Of Integer, Boolean)) = Function(ByVal num) num < 5

// 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 });

// Let the compiler generate the expression tree for
// the lambda expression num => num < 5.
Expression<Func<int, bool>> lambda2 = num => num < 5;

Imutabilidade das árvores de expressão

Árvores de expressão são imutáveis.Isso significa que, se você desejar modificar uma árvore de expressões, você precisa construir uma nova árvore de expressão copiando o já existente e modificá-lo.Você pode usar um visitante da árvore de expressão para percorrer a árvore de expressão existente.Para obter mais informações, consulte Como: Implementar um visitante de árvore de expressões e Como: Modificar árvores de expressão.

Expressões Lambda

Quando uma expressão lambda é atribuída a uma variável do tipo Expression<TDelegate>, o compilador emite uma árvore de expressão que representa a expressão lambda. Por exemplo, alguns métodos de operador de consulta padrão definidos no Queryable classe ter parâmetros de tipo Expression<TDelegate>. Quando você chamar esses métodos, você pode passar uma expressão lambda e o compilador gerará uma árvore de expressão.

The Expression<TDelegate> tipo fornece o Compile método, que compila o código representado pela árvore de expressão para um executável delegado. Esse código executável é equivalente ao código executável que seria foram gerado tinha a expressão lambda sido atribuída a um tipo delegado originalmente.

Observação:

Somente as árvores de expressão que representam funções, ou seja Expression<TDelegate> e seu tipo de pai LambdaExpression, podem ser compilados em código executável. Para executar outros tipos de árvores de expressão, você deve primeiro colocá-los em um LambdaExpression nó. Você pode obter tal um LambdaExpression chamando o Lambda método e passando a árvore de expressão sistema autônomo argumento.

Consulte também

Tarefas

Como: Executar árvores de expressão

Como: Modificar árvores de expressão

Como: Implementar um visitante de árvore de expressões

Conceitos

Árvores de expressão em LINQ

Expressões Lambda

Referência

Expressões lambda (Guia de programação C#)

System.Linq.Expressions