식 트리 는 트리와 유사한 데이터 구조의 코드를 나타내며, 각 노드는 식(예: 메서드 호출 또는 이진 연산 등) x < y
입니다.
LINQ를 사용해보았다면, API 집합의 일부인 Func
형식과 함께 풍부한 라이브러리를 경험할 수 있습니다. (LINQ에 익숙하지 않은 경우 LINQ 자습서 및 이 식 앞에 람다 식 에 대한 문서를 읽으려고 할 수 있습니다.) 식 트리는 함수인 인수와 보다 풍부한 상호 작용을 제공합니다.
LINQ 쿼리를 만들 때 일반적으로 람다 식을 사용하여 함수 인수를 작성합니다. 일반적인 LINQ 쿼리에서 이러한 함수 인수는 컴파일러가 만드는 대리자로 변환됩니다.
식 트리를 사용하는 코드를 이미 작성했습니다. Entity Framework의 LINQ API는 식 트리를 LINQ 쿼리 식 패턴의 인수로 허용합니다. 이를 통해 Entity Framework 는 C#에서 작성한 쿼리를 데이터베이스 엔진에서 실행되는 SQL로 변환할 수 있습니다. 또 다른 예로는 .NET용 인기 모의 프레임워크인 Moq가 있습니다.
보다 풍부한 상호 작용을 하려면 식 트리를 사용해야 합니다. 식 트리는 코드를 검사, 수정 또는 실행하는 구조체로 나타냅니다. 이러한 도구는 런타임 동안 코드를 조작할 수 있는 기능을 제공합니다. 실행 중인 알고리즘을 검사하거나 새 기능을 삽입하는 코드를 작성합니다. 고급 시나리오에서는 실행 중인 알고리즘을 수정하고 C# 식을 다른 환경에서 실행하기 위한 다른 형식으로 변환할 수도 있습니다.
식 트리로 표시되는 코드를 컴파일하고 실행합니다. 식 트리를 빌드하고 실행하면 실행 코드를 동적으로 수정하고, 다양한 데이터베이스에서 LINQ 쿼리를 실행하고, 동적 쿼리를 만들 수 있습니다. LINQ의 식 트리에 대한 자세한 내용은 식 트리를 사용하여 동적 쿼리를 작성하는 방법을 참조하세요.
식 트리는 동적 언어와 .NET 간의 상호 운용성을 제공하고 컴파일러 작성기가 Microsoft CIL(중간 언어) 대신 식 트리를 내보내도록 하기 위해 DLR(동적 언어 런타임)에도 사용됩니다. DLR에 대한 자세한 내용은 동적 언어 런타임 개요를 참조하세요.
C# 또는 Visual Basic 컴파일러가 익명 람다 식을 기반으로 식 트리를 만들거나 네임스페이스를 사용하여 식 트리를 System.Linq.Expressions 수동으로 만들 수 있습니다.
람다 식이 형식 Expression<TDelegate>변수에 할당되면 컴파일러는 코드를 내보내 람다 식을 나타내는 식 트리를 작성합니다.
다음 코드 예제에서는 C# 컴파일러가 람다 num => num < 5
식을 나타내는 식 트리를 만드는 방법을 보여 줍니다.
Expression<Func<int, bool>> lambda = num => num < 5;
코드에서 식 트리를 만듭니다. 각 노드를 만들고 노드를 트리 구조에 연결하여 트리를 빌드합니다. 식 트리 작성에 대한 문서에서 식을 만드는 방법을 알아봅니다.
식 트리는 변경할 수 없습니다. 식 트리를 수정하려면 기존 식 트리를 복사하고 그 안에 있는 노드를 바꿔서 새 식 트리를 생성해야 합니다. 식 트리 방문자를 사용하여 기존 식 트리를 트래버스합니다. 자세한 내용은 식 트리 번역에 대한 문서를 참조하세요.
식 트리를 빌드한 후에는 식 트리가 나타내는 코드를 실행합니다.
제한점
C# 컴파일러는 식 람다(또는 한 줄 람다)에서만 식 트리를 생성합니다. 문 람다(또는 여러 줄 람다)를 구문 분석할 수 없습니다. C#의 람다 식에 대한 자세한 내용은 람다 식을 참조하세요.
식 트리로 잘 변환되지 않는 몇 가지 최신 C# 언어 요소가 있습니다. 식 트리에는 식 또는 await
람다 식이 포함될 async
수 없습니다. C# 6 이상에서 추가된 많은 기능은 식 트리에 기록된 것과 정확히 일치하지 않습니다. 대신, 가능한 경우 최신 기능이 식 트리에 해당하는 이전 구문으로 노출됩니다. 다른 구문을 사용할 수 없습니다. 즉, 식 트리를 해석하는 코드는 새 언어 기능이 도입될 때 동일하게 작동합니다. 그러나 이러한 제한 사항이 있더라도 식 트리를 사용하면 데이터 구조로 표현되는 코드 해석 및 수정에 의존하는 동적 알고리즘을 만들 수 있습니다. Entity Framework와 같은 풍부한 라이브러리가 수행하는 작업을 수행할 수 있습니다.
식 트리는 새로운 표현 노드 유형을 지원하지 않습니다. 식 트리를 해석하는 모든 라이브러리에서 새 노드 형식을 도입하는 것은 호환성을 깨뜨리는 변경입니다. 다음 목록에는 사용할 수 없는 대부분의 C# 언어 요소가 포함되어 있습니다.
- 출력에서 제거된 조건부 메서드
-
base
접근 - 메서드 그룹 및 익명 메서드 식 의 주소 (
&
) 를 포함한 메서드 그룹 식 - 로컬 함수에 대한 참조
- 대입(
=
) 및 문 본문 식을 포함한 문 - 정의 선언만 있는 부분 메서드
- 안전하지 않은 포인터 작업
-
dynamic
작업 -
연산
null
자를 왼쪽 또는default
리터럴로 병합, null 병합 할당 및 null 전파 연산자(?.
) - 다차원 배열 이니셜라이저, 인덱싱된 속성 및 사전 이니셜라이저
- 컬렉션 식
-
throw
식 -
static virtual
액세스 또는abstract
인터페이스 멤버 - 특성이 있는 람다 식
- 보간된 문자열
- UTF-8 문자열 변환 또는 UTF-8 문자열 리터럴
- 변수 인수, 명명된 인수 또는 선택적 인수를 사용하는 메서드 호출
-
System.Index 또는 System.Range를 사용하는 표현, "끝에서부터"(
^
) 연산자 또는 범위 식(..
) -
async
람다 식 또는await
식(포함await foreach
및await using
-
튜플 리터럴, 튜플 변환, 튜플
==
,!=
, 또는with
표현식 -
삭제(
_
), 디스트럭처링 할당, 패턴 매칭is
연산자 또는 패턴 매칭switch
식 - 인수에서 생략된 COM 호출
ref
-
ref
in
또는out
매개 변수,ref
반환 값,out
인수 또는 형식의ref struct
모든 값
.NET