식 트리
업데이트: 2007년 11월
식 트리는 데이터 형태의 언어 수준 코드를 나타냅니다. 데이터는 트리 모양의 구조에 저장됩니다. 식 트리의 각 노드는 식을 나타냅니다. 예를 들어 메서드 호출 또는 x < y와 같은 이진 연산을 나타냅니다.
다음 그림에서는 식 트리 형태로 식과 해당 표현의 예제를 보여 줍니다. 식의 각 부분은 식 트리의 해당 식 트리 노드와 일치하는 색상으로 코딩되어 있습니다. 식 트리 노드의 각 형식도 표시됩니다.
다음 코드 예제에서는 람다 식 num => num < 5(C#) 또는 Function(num) num < 5(Visual Basic)를 나타내는 식 트리를 해당 부분으로 분해하는 방법을 보여 줍니다.
' Import the following namespace to your project: System.Linq.Expressions
' Create an expression tree.
Dim exprTree As Expression(Of Func(Of Integer, Boolean)) = Function(ByVal 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
MsgBox(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
// Add the following using directive to your code file:
// using System.Linq.Expressions;
// Create an expression tree.
Expression<Func<int, bool>> exprTree = num => num < 5;
// Decompose the expression tree.
ParameterExpression param = (ParameterExpression)exprTree.Parameters[0];
BinaryExpression operation = (BinaryExpression)exprTree.Body;
ParameterExpression left = (ParameterExpression)operation.Left;
ConstantExpression right = (ConstantExpression)operation.Right;
Console.WriteLine("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
*/
식 트리 빌드
System.Linq.Expressions 네임스페이스는 수동으로 식 트리를 빌드하기 위한 API를 제공합니다. Expression 클래스에는 특정 형식의 식 트리 노드를 만드는 정적 팩터리 메서드가 들어 있습니다. 예를 들어 명명된 매개 변수 식을 나타내는 ParameterExpression과 메서드 호출을 나타내는 MethodCallExpression이 있습니다. ParameterExpression, MethodCallExpression 및 다른 식 관련 식 트리 형식도 System.Linq.Expressions 네임스페이스에서 정의됩니다. 이러한 형식은 추상 형식 Expression에서 파생됩니다.
컴파일러에서 자동으로 식 트리를 빌드할 수도 있습니다. 컴파일러에서 생성된 식 트리는 항상 Expression<TDelegate> 형식의 노드를 루트로 합니다. 즉, 해당 루트 노드가 람다 식을 나타냅니다.
다음 코드 예제에서는 람다 식 num => num < 5(C#) 또는 Function(num) num < 5(Visual Basic)를 나타내는 식 트리를 만드는 두 가지 방법을 보여 줍니다.
' 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})
' Let the compiler generate the expression tree for
' the lambda expression num => num < 5.
Dim lambda2 As Expression(Of Func(Of Integer, Boolean)) = Function(ByVal num) num < 5
// Add the following using directive to your code file:
// using System.Linq.Expressions;
// Manually build the expression tree for
// the lambda expression num => num < 5.
ParameterExpression numParam = Expression.Parameter(typeof(int), "num");
ConstantExpression five = Expression.Constant(5, typeof(int));
BinaryExpression numLessThanFive = Expression.LessThan(numParam, five);
Expression<Func<int, bool>> lambda1 =
Expression.Lambda<Func<int, bool>>(
numLessThanFive,
new ParameterExpression[] { numParam });
// Let the compiler generate the expression tree for
// the lambda expression num => num < 5.
Expression<Func<int, bool>> lambda2 = num => num < 5;
식 트리 변경 불가능
식 트리는 변경할 수 없습니다. 따라서 식 트리를 수정하려면 기존 식 트리를 복사하고 수정하여 새로운 식 트리를 생성해야 합니다. 식 트리 방문자를 사용하여 기존 식 트리를 이동할 수 있습니다. 자세한 내용은 방법: 식 트리 방문자 구현 및 방법: 식 트리 수정을 참조하십시오.
람다 식
람다 식이 Expression<TDelegate> 형식의 변수에 할당된 경우 컴파일러에서 람다 식을 나타내는 식 트리를 내보냅니다. 예를 들어 Queryable 클래스에서 정의된 일부 표준 쿼리 연산자 메서드에는 Expression<TDelegate> 형식의 매개 변수가 있습니다. 이러한 메서드를 호출할 때 람다 식을 전달할 수 있으며 컴파일러에서 식 트리를 생성합니다.
Expression<TDelegate> 형식은 식 트리에서 나타내는 코드를 실행 대리자로 컴파일하는 Compile 메서드를 제공합니다. 이 실행 코드는 람다 식이 원래 대리자 형식에 할당되었다면 생성되었을 실행 코드와 같습니다.
![]() |
---|
함수를 나타내는 식 트리, 즉 Expression<TDelegate> 및 해당 부모 형식 LambdaExpression만 실행 코드로 컴파일할 수 있습니다. 식 트리의 다른 형식을 실행하려면 먼저 LambdaExpression 노드에 해당 형식을 래핑해야 합니다. Lambda 메서드를 호출하고 식 트리를 인수로 전달하여 이러한 LambdaExpression을 얻을 수 있습니다. |