다음을 통해 공유


방법: 식 트리 수정(Visual Basic)

이 항목에서는 식 트리를 수정하는 방법을 보여줍니다. 식 트리는 수정할 수 없게 설계되어 있어 직접 수정할 수 없습니다. 식 트리를 변경하려면 기존 식 트리의 복사본을 만들고 복사본을 만들 때 필요한 내용을 변경해야 합니다. 클래스를 ExpressionVisitor 사용하여 기존 식 트리를 순회하고 방문하는 각 노드를 복사할 수 있습니다.

표현식 트리를 변경하려면

  1. 콘솔 애플리케이션 프로젝트를 만듭니다.

  2. 파일에 Imports 문을 추가하여 System.Linq.Expressions 네임스페이스에 포함시킵니다.

  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로 변경됩니다. 이렇게 하려면, 조건 VisitBinary 식이 이진 식으로 표현되므로, 클래스는 기본 형식의 AND 메서드를 재정의합니다. 메서드에서 VisitBinary에 전달된 식이 조건부 AND 연산을 나타내는 경우, 코드에서는 조건 OR 연산자 대신 조건 AND 연산자를 포함하는 새로운 식을 생성합니다. 전달된 VisitBinary 식이 조건 AND 작업을 표현하지 않으면, 메서드는 기본 클래스 구현을 따릅니다. 기본 클래스 메서드는 전달되는 식 트리와 같은 노드를 생성하지만 노드에는 해당 하위 트리가 방문자가 재귀적으로 생성하는 식 트리로 대체됩니다.

  4. 파일에 Imports 문을 추가하여 System.Linq.Expressions 네임스페이스에 포함시킵니다.

  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. 애플리케이션을 컴파일하고 실행합니다.

참고하십시오