Partilhar via


Como: Modificar árvores de expressão

Este tópico mostra como modificar uma árvore de expressão.Árvores de expressão são imutáveis, o que significa que eles não podem ser modificados diretamente.Para alterar uma árvore de expressões, você deve criar uma cópia de uma árvore de expressão existente e quando você cria a cópia, faça as alterações necessárias.Você pode usar um visitante da árvore de expressão para percorrer uma árvore de expressões existentes e copiar cada nó em que ele visita.

Para modificar uma árvore de expressão

  1. In Visual Studio, crie um novo Aplicativo de consoleprojeto .

  2. Adicione uma referência a sistema.Core.dll, se ele já não é referenciado.

  3. Adicionar o ExpressionVisitor classe para seu projeto.

    Este código está disponível em Como: Implementar um visitante de árvore de expressões.

    Add using diretivas (ou Imports instruções no Visual Basic) o arquivo para os namespaces a seguir: sistema.Collections.Generic, sistema.Collections.ObjectModel e sistema.Linq.Expressions.

  4. Adicionar o AndAlsoModifier classe para seu projeto.

    Esta classe herda o ExpressionVisitor classe e especializados para modificar as expressões que representam condicional AND operações. Ele altera essas operações por uma condicional AND para uma condicional OR. Para fazer isso, a classe substitui o VisitBinary método do tipo de base, porque condicional AND expressões são representados sistema autônomo expressões binário. No VisitBinary método, se a expressão que é passada para ele representa uma condicional AND operação, o código cria uma nova expressão que contém o condicional OR operador em vez do condicional AND operador. Se a expressão que é passada para VisitBinary não representa uma condicional AND operação, o método passa para a implementação da classe base. Os métodos da classe base construção nós que são semelhantes as árvores de expressão são passados em, mas os nós têm suas árvores de sub-rotina substituídas pelas árvores de expressão são produzidos recursivamente pelo visitante.

    Public Class AndAlsoModifier
        Inherits ExpressionVisitor
    
        Public Function Modify(ByVal expr As Expression) As Expression
            Return Visit(expr)
        End Function
    
        Protected Overrides Function VisitBinary(ByVal b As BinaryExpression) As Expression
            If b.NodeType = ExpressionType.AndAlso Then
                Dim left = Me.Visit(b.Left)
                Dim right = Me.Visit(b.Right)
    
                ' Make this binary expression an OrElse operation instead 
                ' of an AndAlso operation.
                Return Expression.MakeBinary(ExpressionType.OrElse, left, right, _
                                             b.IsLiftedToNull, b.Method)
            End If
    
            Return MyBase.VisitBinary(b)
        End Function
    End Class
    
    public class AndAlsoModifier : ExpressionVisitor
    {
        public Expression Modify(Expression expression)
        {
            return Visit(expression);
        }
    
        protected override Expression VisitBinary(BinaryExpression b)
        {
            if (b.NodeType == ExpressionType.AndAlso)
            {
                Expression left = this.Visit(b.Left);
                Expression right = this.Visit(b.Right);
    
                // Make this binary expression an OrElse operation instead of an AndAlso operation.
                return Expression.MakeBinary(ExpressionType.OrElse, left, right, b.IsLiftedToNull, b.Method);
            }
    
            return base.VisitBinary(b);
        }
    }
    

    Adicionar um using diretiva (ou Imports demonstrativo no Visual Basic) o arquivo para o namespace sistema.Linq.Expressions.

  5. Adicione código para o Main método no arquivo programa.cs (Module1.vb no Visual Basic) para criar uma árvore de expressões e passá-lo para o método que irá modificá-lo.

    O código a seguir cria uma expressão que contenha um condicional AND operação. Ele então cria uma instância do AndAlsoModifier classe e passa a expressão para o Modify método dessa classe. O original e as árvores de expressão modificada são saídas para mostrar a alterar.

    Dim expr As Expression(Of Func(Of String, Boolean)) = _
        Function(name) name.Length > 10 AndAlso name.StartsWith("G")
    
    Console.WriteLine(expr)
    
    Dim modifier As New AndAlsoModifier()
    Dim modifiedExpr = modifier.Modify(CType(expr, Expression))
    
    Console.WriteLine(modifiedExpr)
    
    ' This code produces the following output:
    ' name => ((name.Length > 10) && name.StartsWith("G"))
    ' name => ((name.Length > 10) || name.StartsWith("G"))
    
    
    Expression<Func<string, bool>> expr = name => name.Length > 10 && name.StartsWith("G");
    Console.WriteLine(expr);
    
    AndAlsoModifier treeModifier = new AndAlsoModifier();
    Expression modifiedExpr = treeModifier.Modify((Expression) expr);
    
    Console.WriteLine(modifiedExpr);
    
    /*  This code produces the following output:
    
        name => ((name.Length > 10) && name.StartsWith("G"))
        name => ((name.Length > 10) || name.StartsWith("G"))
    */
    
    

    Adicionar um using diretiva (ou Imports demonstrativo no Visual Basic) o arquivo para o namespace sistema.Linq.Expressions.

  6. Compile e execute o aplicativo.

Consulte também

Tarefas

Como: Executar árvores de expressão

Demonstra Passo a passo: Criar um provedor de LINQ IQueryable

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

Conceitos

Árvores de Expressão