Gewusst wie: Bearbeiten von Ausdrucksstrukturen (C# und Visual Basic)

In diesem Thema wird beschrieben, wie eine Ausdrucksbaumstruktur geändert wird. Ausdrucksbaumstrukturen sind unveränderlich. Das bedeutet, dass sie nicht direkt geändert werden können. Um eine Ausdrucksbaumstruktur zu ändern, müssen Sie eine Kopie einer vorhandenen Ausdrucksbaumstruktur erstellen und beim Erstellen der Kopie die erforderlichen Änderungen vornehmen. Sie können die ExpressionVisitor-Klasse verwenden, um eine vorhandene Ausdrucksbaumstruktur zu durchlaufen und jeden aufgerufenen Knoten zu kopieren.

Hinweis

Den Quellecode für die ExpressionVisitor-Klasse finden Sie auf der CodePlex-Website.

So ändern Sie eine Ausdrucksbaumstruktur

  1. Erstellen Sie in Visual Studio ein neues Konsolenanwendungsprojekt.

  2. Fügen Sie dem Projekt die AndAlsoModifier-Klasse hinzu.

    Diese Klasse erbt die ExpressionVisitor-Klasse und wird spezialisiert, um Ausdrücke zu ändern, die bedingte AND-Operationen darstellen. Die Klasse ändert diese Operationen von einem bedingten AND in ein bedingtes OR. Dazu überschreibt die Klasse die VisitBinary-Methode des Basistyps, da bedingte AND-Ausdrücke als binäre Ausdrücke dargestellt werden. Für die VisitBinary-Methode gilt Folgendes: Wenn der Ausdruck, der an die Methode übergeben wird, eine bedingte AND-Operation darstellt, erstellt der Code einen neuen Ausdruck, der den bedingten Operator OR anstelle des bedingten Operators AND enthält. Wenn der Ausdruck, der an VisitBinary übergeben wird, keine bedingte AND-Operation darstellt, richtet sich die Methode nach der Basisklassenimplementierung. Die Basisklassenmethode erstellt Knoten, die den übergebenen Ausdrucksbaumstrukturen ähneln. In diesem Fall sind die Teilstrukturen der Knoten jedoch durch die Ausdrucksbaumstrukturen ersetzt, die vom Besucher rekursiv erstellt werden.

    Fügen Sie eine using-Direktive (oder Imports-Anweisung in Visual Basic) für den System.Linq.Expressions-Namespace der Datei hinzu.

    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. Fügen Sie der Main-Methode in der Datei Program.cs (Module1.vb in Visual Basic) Code hinzu, um eine Ausdrucksbaumstruktur zu erstellen und an die Methode zu übergeben, die sie ändert.

    Der folgende Code erstellt einen Ausdruck, der eine bedingte AND-Operation enthält. Anschließend wird eine Instanz der AndAlsoModifier-Klasse erstellt, und der Ausdruck wird an die Modify-Methode dieser Klasse übergeben. Sowohl die ursprüngliche als auch die geänderte Ausdrucksbaumstruktur werden ausgegeben, um die Änderung anzuzeigen.

    Fügen Sie eine using-Direktive (oder Imports-Anweisung in Visual Basic) für den System.Linq.Expressions-Namespace der Datei hinzu.

            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. Kompilieren Sie die Anwendung, und führen Sie sie aus.

Siehe auch

Aufgaben

Gewusst wie: Ausführen von Ausdrucksbaumstrukturen (C# und Visual Basic)

Konzepte

Ausdrucksbaumstrukturen (C# und Visual Basic)