2012-02-27 1 views
0

런타임에 표현식 트리를 빌드 할 때 코드 이 나오지 않습니다.표현식 트리가 런타임 코드를 방출합니까?

ParameterExpression p = Expression.Parameter (typeof (string), "s"); 
    MemberExpression stringLength = Expression.Property (p, "Length"); 
    ConstantExpression five = Expression.Constant (5); 
    BinaryExpression comparison = Expression.LessThan (stringLength, five); 
    Expression<Func<string, bool>> lambda= Expression.Lambda<Func<string, bool>> (comparison, p); 

    Func<string, bool> runnable = lambda.Compile(); 

이 코드는 늘 IL 될 : 그것은

는 지금이 코드를 가지고 말할 수 ... ... 좋아

런타임에 .NET 코드를 표현하는 방법? 물론 될 것입니다! (어쩌면 마지막 줄은 컴파일 할 때까지 코드를 내 보내지 않을 것이다.하지만 코드가 나오는 첫 번째 줄은!)

그래서 나는 무엇을 저장하고 있는가?

좋아요. 그래서 처음 5 행은 코드를 내보내고 마지막 하나는 ... 큰 문제가 아닙니다.

내가 무엇이 누락 되었습니까? 전체 사진을 보여 주실 수 있습니까?

+0

컴파일 할 때 표현식 트리가 (DynamicMethod를 사용하여) IL로 변환됩니다. – leppie

+0

@leppie와 첫 번째 5 줄은 IL에 없습니까? –

+0

음, 처음에는 컴파일 된 정상적인 코드입니다. 익스프레션에는 일리노이에 대한 개념이 없습니다. 추상화입니다. 일리노이로 내보낼 수 있지만 그렇게 할 필요는 없습니다 (예 : 자신의 x86 ASM 또는 GPU 코드 등을 내보낼 수 있음). – leppie

답변

1

Expression Tree를 사용하면 코드 자체 대신 일부 코드에 대한 설명을 작성합니다. Expression Trees는 '컴파일 할 때 컴파일해서는 안되는'정규 코드 작성의 컨텍스트에서 사용하면 안됩니다. 보다 동적 인 시나리오에서 사용해야합니다.

표시하는 표현 트리는 s.Length < 5으로 컴파일되고 bool isStringSmallerThan5 = runnable("MyString")과 함께 runnable을 호출합니다.

표현식 트리의 개념은 일부 코드를 설명하고 런타임에 컴파일 할 수 있다는 것입니다. 즉, 다음을 수행 할 수 있습니다.

BinaryExpression comparison = null; 
if (lessThen) 
{ 
    comparison = Expression.LessThan(stringLength, five); 
} 
else 
{ 
    comparison = Expression.GreaterThan(stringLength, five); 
} 

이제 런타임시 코드 동작을 변경할 수 있습니다!

표현식 트리의 가장 큰 용도는 공급자가이를 해석 할 수 있다는 것입니다. 예를 들어 Linq To Entities는 표현식 트리를 사용하여 데이터베이스에 대해 실행할 수있는 SQL 코드로 컴파일합니다. LinqToXml은 Expression Trees로 할 수있는 또 다른 예입니다.

좋은 blog post으로 시작하겠습니다.

+0

나는 HOw를 볼 수있다. Im 9000을 할 것이다. 내 코드에있다면, 내가 동적으로 행동하기를 원한다. ... –

+0

달성하고자하는 것은 무엇인가? 표현식 트리는 Linq와 같은 것들에서 주로 사용됩니다. 실제 동적 코드를 만드는 것이 주요 시나리오는 아닙니다. '9000'시나리오가 다른 경우 어떻게 지원할 수 있습니까? –

+0

나는 .... linq이 가장 간단한 쿼리에서 그것을 사용하는 방법에 대해 아주 작은 예제를 알려주시겠습니까? –

0

표현 트리는 표현 내용을보다 복잡하게 사용할 수 있으므로 메소드에서 표현 트리를 수신 할 때 유용합니다. 메소드에서 술어를 수신하면,이를 대상에 대해 실행하고 결과를 점검 할 수 있습니다. 표현식 트리를 나타내는 표현식 트리를 받으면 구문 분석을 통해 유용한 표현을 수행 할 수 있습니다. LINQ는이 많은 장소를 활용하지만 "Where"방법 중 하나를 사용하는 예입니다. 일리노이 대신 표현식 트리를 잡으면 전체 '선택'을 수행하고 구체화 된 결과에 대한 술어를 실행하는 대신 SQL로 변환하는 것이 상대적으로 간단합니다.

+0

고마워요.하지만 "Code 방출"의 관점에서 질문을했습니다 ... 제가 여기에서 무엇을 저장하고 있습니까? 그리고 표현식 트리 대신 술어 (predicate) 대신에 "compile"해야만합니다 ... 그래서 나는 무엇을 얻었습니까? 나는 그 지점을 잡을 수 없다. (나는 거기에 하나 있다는 것을 알고있다.)). –

+0

IMHO 요점은 당신이 더 "우호"한 중개자 표현을한다는 것입니다. 그러나 당신은 확실히 어떤 시점에서 그것을 컴파일해야 할 것입니다. 내보다 더 똑똑한 사람이 더 나은 설명을 볼 수있게 해준다. – faester