2009-01-21 9 views
0

여기 내 질문에 대한 컨텍스트 :대리자 인스턴스를 람다 식으로 캐스팅 할 수 있습니까?

일반적인 기술은 메서드의 매개 변수를 대리자가 아닌 람다 식으로 선언하는 것입니다. 이것은 메서드가 대리자 인스턴스의 본문에서 메서드 호출의 이름을 찾는 것과 같은 흥미로운 작업을 수행하는 식을 검사 할 수 있도록하기위한 것입니다.

Resharper의 인텔리 센스 기능 중 일부가 손실되는 문제가 있습니다. 메서드의 매개 변수가 대리자로 선언 된 경우 Resharper는이 메서드에 대한 호출을 작성할 때 x => x 구문을 사용하여이 메서드에 인수 값을 제공하도록 도와줍니다.

그래서 ... 다시 내 질문에 내가 추적을 할 싶습니다

MethodThatTakesDelegate(s => s.Length); 
} 

private void MethodThatTakesDelegate(Func<string, object> func) 
{ 
    //convert func into expression 
    //Expression<Func<string, object>> expr = "code I need to write" 

    MethodThatTakesExpression(expr); 
} 


private void MethodThatTakesExpression(Expression<Func<string, object>> expr) 
{ 
    //code here to determine the name of the property called against string (ie the Length) 
} 
+0

나는 [이 블로그 엔트리] (http://blogs.msdn.com/charlie/archive/2008/01/31/expression-tree-basics.aspx)를 통해 광택을 내고 있었고, 직접 과제를 수행하는 것처럼 보였다. . 그게 너에게 효과가 없을까? – plinth

답변

2

"람다 식"이라는 용어를 사용하는 모든 곳에서는 실제로 "식 트리"를 의미합니다.

람다 식 소스 코드의 비트이다되는

parameters => code 

예컨대

x => x * 2 

식 트리가 System.Linq.Expressions.Expression 클래스의 인스턴스 (또는 오히려 파생 클래스 중 하나로) 데이터로서 코드를 나타낸다.

람다 식은 어느 식 트리 (또는 오히려, 실행시 발현 트리를 생성하는 코드) 또는 대리자 인스턴스로 컴파일러에 의해 변환된다.

LambdaExpression (Expression의 하위 클래스 중 하나임) 인스턴스를 대리자로 컴파일 할 수 있지만 다른 방법으로는 사용할 수 없습니다.

이론적으로

일리노이에 따라 이러한 "디 컴파일러"를 쓸 수있을 수는 MethodBase.GetMethodBody하여 일부 상황을 반환하지만, 현재 식 트리로 표현할 수없는 다양한 대표가있다. 표현 트리는 또는 명령문 블록 대신 표현을 나타냅니다. 따라서 루핑, 분기 (조건부 제외), 할당 등은 없습니다.나는 이것이 .NET 4.0에서 변경 될 수 있다고 믿지만, 정말로 좋은 이유가 없다면 Microsoft의 역 컴파일 단계를 기대하지는 않습니다.

0

나는 당신이 여기에서 원하는 것을 달성하는 것이 가능하다 생각하지 않는다. 코드의 주석을 보면 MethodThatTakesExpression에서 할당을 수행 한 속성의 이름을 캡처하려는 것처럼 보입니다. 이것은 속성 액세스의 컨텍스트를 캡쳐하는 식 트리 람다식이 필요합니다.

대리인을 MethodThatTakesDelegate로 전달할 때이 컨텍스트가 손실됩니다. 대리인은 메서드 정보에 대한 컨텍스트가 아닌 메서드 주소 만 저장합니다. 이 변환이 이루어지면 다시 가져올 수 없습니다.

이 방법이 불가능한 이유 중 하나는 대리자를지지하는 명명 된 메서드가 없을 수도 있다는 것입니다. ReflectionEmit을 사용하여 이름이 전혀없고 메모리에만 존재하는 메소드를 생성 할 수 있습니다. 이것을 Func 객체에 할당 할 수도 있습니다.

0

아니요, 불가능합니다.