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