Condividi tramite


Procedura: modificare strutture ad albero dell'espressione

Aggiornamento: novembre 2007

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 un visitatore della struttura ad albero dell'espressione per attraversare una tale struttura esistente e copiare ogni nodo visitato.

Per modificare una struttura ad albero dell'espressione

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

  2. Aggiungere un riferimento a System.Core.dll, se non è già presente.

  3. Aggiungere la classe ExpressionVisitor al progetto.

    Questo codice è disponibile in Procedura: implementare un visitatore della struttura ad albero dell'espressione.

    Aggiungere direttive using (o istruzioni Imports in Visual Basic) al file per i seguenti spazi dei nomi: System.Collections.Generic, System.Collections.ObjectModel e System.Linq.Expressions.

  4. 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.

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

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

  5. 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.

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

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

  6. Compilare ed eseguire l'applicazione.

Vedere anche

Attività

Procedura: eseguire strutture ad albero dell'espressione

Procedura dettagliata: creazione di un provider LINQ IQueryable

Procedura: implementare un visitatore della struttura ad albero dell'espressione

Concetti

Strutture ad albero dell'espressione