Porady: modyfikowanie drzew wyrażeń (Visual Basic)
W tym temacie przedstawiono sposób modyfikowania drzewa wyrażeń. Drzewa wyrażeń są niezmienne, co oznacza, że nie można ich modyfikować bezpośrednio. Aby zmienić drzewo wyrażeń, należy utworzyć kopię istniejącego drzewa wyrażeń i podczas tworzenia kopii wprowadzić wymagane zmiany. Możesz użyć ExpressionVisitor klasy, aby przejść przez istniejące drzewo wyrażeń i skopiować każdy węzeł, który odwiedza.
Aby zmodyfikować drzewo wyrażeń
Utwórz nowy projekt aplikacja konsolowa.
Dodaj instrukcję
Imports
do pliku dlaSystem.Linq.Expressions
przestrzeni nazw.Dodaj klasę
AndAlsoModifier
do projektu.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
Ta klasa dziedziczy klasę ExpressionVisitor i jest wyspecjalizowana do modyfikowania wyrażeń reprezentujących operacje warunkowe
AND
. Zmienia te operacje z warunkowego na warunkowyAND
OR
. W tym celu klasa zastępuje metodę VisitBinary typu podstawowego, ponieważ wyrażenia warunkoweAND
są reprezentowane jako wyrażenia binarne. W metodzieVisitBinary
, jeśli wyrażenie przekazane do niego reprezentuje operację warunkowąAND
, kod tworzy nowe wyrażenie, które zawiera operator warunkowyOR
zamiast operatora warunkowegoAND
. Jeśli wyrażenie przekazane doVisitBinary
elementu nie reprezentuje operacji warunkowejAND
, metoda odchyli się do implementacji klasy bazowej. Metody klasy bazowej konstruują węzły, które są podobne do drzew wyrażeń, które są przekazywane, ale węzły mają swoje drzewa podrzędne zastąpione drzewami wyrażeń, które są tworzone rekursywnie przez gościa.Dodaj instrukcję
Imports
do pliku dlaSystem.Linq.Expressions
przestrzeni nazw.Dodaj kod do
Main
metody w pliku Module1.vb, aby utworzyć drzewo wyrażeń i przekazać go do metody, która ją zmodyfikuje.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"))
Kod tworzy wyrażenie zawierające operację warunkową
AND
. Następnie tworzy wystąpienieAndAlsoModifier
klasy i przekazuje wyrażenie doModify
metody tej klasy. Zarówno oryginalne, jak i zmodyfikowane drzewa wyrażeń są zwracane w celu wyświetlenia zmiany.Skompiluj i uruchom aplikację.