HOW TO:修改運算式樹狀架構 (C# 和 Visual Basic)
本主題說明如何修改運算式樹狀架構。運算式樹狀架構是不可變動的,這表示不能直接修改運算式樹狀架構。若要變更運算式樹狀架構,您必須建立現有運算式樹狀架構的複本,並且在建立複本時進行必要的變更。您可以使用 ExpressionVisitor 類別,周遊現有運算式樹狀架構,並複製每個造訪的節點。
注意事項 |
---|
您可以在 CodePlex (英文) 網站上找到 ExpressionVisitor 類別的原始程式碼。 |
若要修改運算式樹狀架構
在 Visual Studio 中建立新的 [主控台應用程式] 專案。
將 AndAlsoModifier 類別加入至專案。
此類別會繼承 ExpressionVisitor 類別,並針對代表條件式 AND 作業的運算式進行修改。其中會將這些作業從條件式 AND 作業變更為條件式 OR 作業。為了這麼做,此類別會覆寫基底型別 (Base Type) 的 VisitBinary 方法,因為條件式 AND 運算式會以二進位運算式來表示。在 VisitBinary 方法中,如果傳遞給它的運算式代表的是條件式 AND 作業,則程式碼會建構新的運算式,其中會以條件式 OR 運算子取代條件式 AND 運算子。如果傳遞給 VisitBinary 的運算式代表的不是條件式 AND 作業,則由基底類別 (Base Class) 實作來決定方法。基底類別方法會建構類似傳入之運算式樹狀架構的節點,但是這些節點的子樹狀結構會由訪問項以遞迴方式產生的運算式樹狀架構來取代。
在檔案中為 System.Linq.Expressions 命名空間加入 using 指示詞 (或者在 Visual Basic 中為 Imports 陳述式)。
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); } }
在 Program.cs (Visual Basic 中為 Module1.vb) 中將程式碼加入至 Main 方法以建立運算式樹狀架構,並將此架構傳遞給將修改其內容的方法。
下列程式碼會建立包含條件式 AND 作業的運算式。接著,它會建立 AndAlsoModifier 類別的執行個體,並將運算式傳遞給此類別的 Modify 方法。此時會輸出原始和修改後的運算式樹狀架構,以顯示變更的情形。
在檔案中為 System.Linq.Expressions 命名空間加入 using 指示詞 (或者在 Visual Basic 中為 Imports 陳述式)。
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")) */
編譯及執行應用程式。
請參閱
工作
HOW TO:執行運算式樹狀結構 (C# 和 Visual Basic)