Procedura: modificare strutture ad albero dell'espressione (C# e Visual Basic)

In questo argomento viene illustrato come modificare una struttura ad albero dell'espressione. Le strutture ad albero dell'espressione sono immutabili, ovvero non possono essere modificate direttamente. Per modificare una struttura ad albero dell'espressione è necessario creare una copia di una struttura esistente e apportare le modifiche necessarie durante le creazione di tale copia. È possibile utilizzare la classe ExpressionVisitor per attraversare una struttura ad albero dell'espressione e copiare ogni nodo visitato.

Nota

Il codice sorgente per la classe ExpressionVisitor è disponibile nel sito Web CodePlex.

Per modificare una struttura ad albero dell'espressione

  1. In Visual Studio creare un nuovo progetto Applicazione console.

  2. Aggiungere la classe AndAlsoModifier al progetto.

    Questa classe eredita la classe ExpressionVisitor ed è specializzata per modificare le espressioni che rappresentano operazioni AND condizionali. Queste operazioni vengono modificate da AND condizionale in OR condizionale. A questo scopo la classe esegue l'override del metodo VisitBinary del tipo di base, in quanto le espressioni AND condizionali sono rappresentate come espressioni binarie. Nel metodo VisitBinary, se l'espressione passata rappresenta un'operazione AND condizionale, il codice costruisce una nuova espressione che contiene l'operatore OR condizionale anziché l'operatore AND condizionale. Se l'espressione passata a VisitBinary non rappresentare un'operazione AND condizionale, il metodo rinvia all'implementazione della classe base. I metodi della classe base costruiscono nodi simili alle strutture ad albero dell'espressione a cui vengono passati, tuttavia le sottostrutture ad albero dei nodi vengono sostituite con le strutture ad albero dell'espressione prodotte in modo ricorsivo dal visitatore.

    Aggiungere una direttiva using (o un'istruzione Imports in Visual Basic) al file per lo spazio dei nomi System.Linq.Expressions.

    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);
        }
    }
    
  3. Aggiungere codice al metodo Main nel file Program.cs (Module1.vb in Visual Basic) per creare una struttura ad albero dell'espressione e passarla al metodo che la modificherà.

    Nel codice seguente viene creata un'espressione che contiene un'operazione AND condizionale. Viene quindi creata un'istanza della classe AndAlsoModifier e viene passata l'espressione al metodo Modify di questa classe. Per mostrare la modifica viene restituito l'output delle strutture ad albero dell'espressione originale e modificata.

    Aggiungere una direttiva using (o un'istruzione Imports in Visual Basic) al file per lo spazio dei nomi System.Linq.Expressions.

            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"))
                */
    
    
  4. Compilare l'applicazione ed eseguirla.

Vedere anche

Attività

Procedura: eseguire strutture ad albero dell'espressione (C# e Visual Basic)

Concetti

Strutture ad albero dell'espressione (C# e Visual Basic)