次の方法で共有


方法: 式ツリーを変更する (Visual Basic)

このトピックでは、式ツリーを変更する方法について説明します。 式ツリーは不変です。つまり、式ツリーを直接変更することはできません。 式ツリーを変更するには、既存の式ツリーのコピーを作成し、コピーを作成するときに必要な変更を行う必要があります。 ExpressionVisitor クラスを使用して、既存の式ツリーを走査し、アクセスする各ノードをコピーできます。

式ツリーを変更するには

  1. 新しい コンソール アプリケーション プロジェクトを作成します。

  2. System.Linq.Expressions名前空間のファイルに Imports ステートメントを追加します。

  3. AndAlsoModifier クラスをプロジェクトに追加します。

    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
    

    このクラスは、 ExpressionVisitor クラスを継承し、条件付き AND 操作を表す式を変更するために特化されています。 これらの操作は、条件付き AND から条件付き ORに変更されます。 これを行うには、条件付きAND式がバイナリ式として表されるため、このクラスは基本型のVisitBinary メソッドをオーバーライドします。 VisitBinary メソッドで、渡される式が条件付きAND操作を表す場合、コードは条件付きOR演算子ではなく、条件付きAND演算子を含む新しい式を構築します。 VisitBinaryに渡される式が条件付きAND操作を表さない場合、メソッドは基底クラスの実装に遅延します。 基底クラスメソッドは、渡される式ツリーのようなノードを構築しますが、ノードのサブ ツリーは、ビジターによって再帰的に生成される式ツリーに置き換えられます。

  4. System.Linq.Expressions名前空間のファイルに Imports ステートメントを追加します。

  5. Module1.vb ファイルの Main メソッドにコードを追加して式ツリーを作成し、それを変更するメソッドに渡します。

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

    このコードは、条件付き AND 操作を含む式を作成します。 次に、 AndAlsoModifier クラスのインスタンスを作成し、このクラスの Modify メソッドに式を渡します。 元の式ツリーと変更された式ツリーの両方が出力され、変更が表示されます。

  6. アプリケーションをコンパイルして実行する。

こちらも参照ください