식 트리는 트리와 유사한 데이터 구조의 코드를 나타내며, 각 노드는 식(예: 메서드 호출 또는 이진 연산 등) x < y
입니다.
식 트리로 표시되는 코드를 컴파일하고 실행할 수 있습니다. 이렇게 하면 실행 코드를 동적으로 수정하고, 다양한 데이터베이스에서 LINQ 쿼리를 실행하고, 동적 쿼리를 만들 수 있습니다. LINQ의 식 트리에 대한 자세한 내용은 방법: 식 트리를 사용하여 동적 쿼리 작성(Visual Basic)을 참조하세요.
식 트리는 DLR(동적 언어 런타임)에도 사용되어 동적 언어와 .NET Framework 간의 상호 운용성을 제공하고 컴파일러 작성기가 CIL(공용 중간 언어) 대신 식 트리를 내보날 수 있도록 합니다. DLR에 대한 자세한 내용은 동적 언어 런타임 개요를 참조하세요.
C# 또는 Visual Basic 컴파일러가 익명 람다 식을 기반으로 식 트리를 만들거나 네임스페이스를 사용하여 식 트리를 System.Linq.Expressions 수동으로 만들 수 있습니다.
람다 식에서 식 트리를 생성하기
람다 식이 형식 Expression<TDelegate>변수에 할당되면 컴파일러는 코드를 내보내 람다 식을 나타내는 식 트리를 작성합니다.
Visual Basic 컴파일러는 식 람다(또는 한 줄 람다)에서만 식 트리를 생성할 수 있습니다. 문장 람다(또는 여러 줄 람다)를 구문 분석할 수 없습니다. Visual Basic의 람다 식에 대한 자세한 내용은 람다 식을 참조하세요.
다음 코드 예제에서는 Visual Basic 컴파일러가 람다 Function(num) num < 5
식을 나타내는 식 트리를 만드는 방법을 보여 줍니다.
Dim lambda As Expression(Of Func(Of Integer, Boolean)) =
Function(num) num < 5
API를 사용하여 식 트리 만들기
API를 사용하여 식 트리를 만들려면 클래스를 Expression 사용합니다. 이 클래스에는 변수 또는 매개 변수ParameterExpression를 나타내는 식 트리 노드 또는 메서드 호출을 나타내는 특정 형식MethodCallExpression의 식 트리 노드를 만드는 정적 팩터리 메서드가 포함되어 있습니다. ParameterExpression, MethodCallExpression 및 다른 표현식 전용 형식도 System.Linq.Expressions 네임스페이스에 정의됩니다. 이러한 형식은 추상 형식 Expression에서 파생합니다.
다음 코드 예제에서는 API를 사용하여 람다 식을 Function(num) num < 5
나타내는 식 트리를 만드는 방법을 보여 줍니다.
' Import the following namespace to your project: System.Linq.Expressions
' Manually build the expression tree for the lambda expression num => num < 5.
Dim numParam As ParameterExpression = Expression.Parameter(GetType(Integer), "num")
Dim five As ConstantExpression = Expression.Constant(5, GetType(Integer))
Dim numLessThanFive As BinaryExpression = Expression.LessThan(numParam, five)
Dim lambda1 As Expression(Of Func(Of Integer, Boolean)) =
Expression.Lambda(Of Func(Of Integer, Boolean))(
numLessThanFive,
New ParameterExpression() {numParam})
.NET Framework 4 이상에서 식 트리 API는 루프, 조건부 블록 및 블록 try-catch
과 같은 할당 및 제어 흐름 식도 지원합니다. API를 사용하면 Visual Basic 컴파일러에서 람다 식에서 만들 수 있는 것보다 더 복잡한 식 트리를 만들 수 있습니다. 다음 예제에서는 숫자의 계수를 계산하는 식 트리를 만드는 방법을 보여 줍니다.
' Creating a parameter expression.
Dim value As ParameterExpression =
Expression.Parameter(GetType(Integer), "value")
' Creating an expression to hold a local variable.
Dim result As ParameterExpression =
Expression.Parameter(GetType(Integer), "result")
' Creating a label to jump to from a loop.
Dim label As LabelTarget = Expression.Label(GetType(Integer))
' Creating a method body.
Dim block As BlockExpression = Expression.Block(
New ParameterExpression() {result},
Expression.Assign(result, Expression.Constant(1)),
Expression.Loop(
Expression.IfThenElse(
Expression.GreaterThan(value, Expression.Constant(1)),
Expression.MultiplyAssign(result,
Expression.PostDecrementAssign(value)),
Expression.Break(label, result)
),
label
)
)
' Compile an expression tree and return a delegate.
Dim factorial As Integer =
Expression.Lambda(Of Func(Of Integer, Integer))(block, value).Compile()(5)
Console.WriteLine(factorial)
' Prints 120.
자세한 내용은 Visual Studio 2010에서 식 트리를 사용하여 동적 메서드 생성을 참조하세요. 이 메서드는 이후 버전의 Visual Studio에도 적용됩니다.
구문 분석 식 트리
다음 코드 예제에서는 람다 식을 Function(num) num < 5
나타내는 식 트리를 해당 부분으로 분해할 수 있는 방법을 보여 줍니다.
' Import the following namespace to your project: System.Linq.Expressions
' Create an expression tree.
Dim exprTree As Expression(Of Func(Of Integer, Boolean)) = Function(num) num < 5
' Decompose the expression tree.
Dim param As ParameterExpression = exprTree.Parameters(0)
Dim operation As BinaryExpression = exprTree.Body
Dim left As ParameterExpression = operation.Left
Dim right As ConstantExpression = operation.Right
Console.WriteLine(String.Format("Decomposed expression: {0} => {1} {2} {3}",
param.Name, left.Name, operation.NodeType, right.Value))
' This code produces the following output:
'
' Decomposed expression: num => num LessThan 5
표현식 트리의 불변성
식 표현 트리는 불변이어야 합니다. 즉, 식 트리를 수정하려면 기존 식 트리를 복사하고 그 안에 있는 노드를 바꿔서 새 식 트리를 생성해야 합니다. 표현식 트리 방문자를 사용하여 기존 표현식 트리를 순회할 수 있습니다. 자세한 내용은 방법: 식 트리 수정(Visual Basic)을 참조하세요.
표현식 트리 컴파일
Expression<TDelegate> 형식은 식 트리가 나타내는 코드를 실행 가능한 대리자로 컴파일하는 Compile 메서드를 제공합니다.
다음 코드 예제에서는 식 트리를 컴파일하고 결과 코드를 실행하는 방법을 보여 줍니다.
' Creating an expression tree.
Dim expr As Expression(Of Func(Of Integer, Boolean)) =
Function(num) num < 5
' Compiling the expression tree into a delegate.
Dim result As Func(Of Integer, Boolean) = expr.Compile()
' Invoking the delegate and writing the result to the console.
Console.WriteLine(result(4))
' Prints True.
' You can also use simplified syntax
' to compile and run an expression tree.
' The following line can replace two previous statements.
Console.WriteLine(expr.Compile()(4))
' Also prints True.
자세한 내용은 방법: 식 트리 실행(Visual Basic)을 참조하세요.
참고하십시오
.NET