방법: 식 트리 수정
업데이트: 2007년 11월
이 항목에서는 식 트리를 수정하는 방법을 보여 줍니다. 식 트리는 변경 불가능하므로 직접 수정할 수 없습니다. 식 트리를 변경하려면 기존 식 트리의 복사본을 만들어야 하고, 복사본을 만들 때 필요한 변경 작업을 수행해야 합니다. 식 트리 방문자를 사용하여 기존 식 트리를 이동하고 방문한 각 노드를 복사할 수 있습니다.
식 트리를 수정하려면
Visual Studio에서 콘솔 응용 프로그램 프로젝트를 새로 만듭니다.
아직 참조되지 않은 경우 System.Core.dll에 대한 참조를 추가합니다.
ExpressionVisitor 클래스를 프로젝트에 추가합니다.
이 코드는 방법: 식 트리 방문자 구현에서 사용할 수 있습니다.
System.Collections.Generic, System.Collections.ObjectModel 및 System.Linq.Expressions 네임스페이스에 대한 using 지시문(Visual Basic의 경우 Imports 문)을 파일에 추가합니다.
AndAlsoModifier 클래스를 프로젝트에 추가합니다.
이 클래스는 ExpressionVisitor 클래스를 상속하며 조건부 AND 작업을 나타내는 식을 수정하는 데 사용됩니다. 이러한 작업을 조건부 AND에서 조건부 OR로 변경합니다. 조건부 AND 식은 이진 식으로 표시되므로 이 작업을 위해 클래스는 기본 형식의 VisitBinary 메서드를 재정의합니다. VisitBinary 메서드에서 전달된 식이 조건부 AND 연산을 나타내는 경우 코드에서 조건부 AND 연산자 대신 조건부 OR 연산자를 포함하는 새 식이 생성됩니다. VisitBinary로 전달된 식이 조건부 AND 연산을 나타내지 않으면 메서드에서 기본 클래스 구현을 따릅니다. 기본 클래스 메서드는 전달된 식 트리와 같은 노드를 생성하지만 노드의 하위 트리가 방문자에 의해 재귀적으로 생성된 식 트리로 바뀝니다.
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 문)을 파일에 추가합니다.
응용 프로그램을 컴파일하여 실행합니다.