2009-08-04 3 views
2

Func로 위임 된 메서드의 이름을 얻고 싶습니다.Func에서 실행 된 호출 된 메서드의 이름 검색

Func<MyObject, object> func = x => x.DoSomeMethod(); 
string name = ExtractMethodName(func); // should equal "DoSomeMethod" 

어떻게하면됩니까?

- 자랑 권리를 위해 -

는 해당 인스턴스에서 속성 이름을 반환 가진, ExtractMethodName는 속성 호출 작동합니다.

예 :

Func<MyObject, object> func = x => x.Property; 
string name = ExtractMethodName(func); // should equal "Property" 

답변

11

Look Ma! 표현의 나무가 없습니다!

다음은 기본 람다의 IL 스트림에서 메타 데이터 토큰을 가져 와서 해결하는 빠르고 자세한 구현 고유 버전입니다.

private static string ExtractMethodName(Func<MyObject, object> func) 
{ 
    var il = func.Method.GetMethodBody().GetILAsByteArray(); 

    // first byte is ldarg.0 
    // second byte is callvirt 
    // next four bytes are the MethodDef token 
    var mdToken = (il[5] << 24) | (il[4] << 16) | (il[3] << 8) | il[2]; 
    var innerMethod = func.Method.Module.ResolveMethod(mdToken); 

    // Check to see if this is a property getter and grab property if it is... 
    if (innerMethod.IsSpecialName && innerMethod.Name.StartsWith("get_")) 
    { 
     var prop = (from p in innerMethod.DeclaringType.GetProperties() 
        where p.GetGetMethod() == innerMethod 
        select p).FirstOrDefault(); 
     if (prop != null) 
      return prop.Name; 
    } 

    return innerMethod.Name; 
} 
+0

감사! 나는 물건이 그 펑키를 얻을 것을 기대하지 않았다. 그러나 그것은 희망에 따라 움직이게된다. – berko

+1

메서드가 다른 모듈에 있으면 어떻게됩니까? 함수 매개 변수의 모듈을 가져야하지 않습니까? – SLaks

0

일반적인 경우에는 가능하지 않다고 생각합니다. 어떤 경우 :

Func<MyObject, object> func = x => x.DoSomeMethod(x.DoSomeOtherMethod()); 

무엇을 기대합니까?

반성을 사용하면 Func 개체를 열고 내부에서 수행되는 작업을 볼 수 있지만 특정 경우에만이를 해결할 수 있습니다.

+0

내가 가진 대답을 원하면 "DoSomeMethod"가되어야합니다. 내가 제공 한 속성 예제가 실제로 Func 심문의 잠재적 인 복잡성을 제한하기 때문에 실제로 더 쉬울 수 있습니까? – berko

0

여기 내 해킹 대답 체크 아웃 : 나는 그것을 Expression<Func<...>> 대신 Func를 사용하는 다른 방법을했던 과거

Why is there not a `fieldof` or `methodof` operator in C#?

,하지만 난 훨씬 덜 기쁘게 결과에 있었다. 내 fieldof 메서드에서 필드를 검색하는 데 사용 된 MemberExpression은 속성을 사용할 때 PropertyInfo을 반환합니다.

편집 # 1 :이 문제의 부분 집합에 대한 작동합니다

Func<object> func = x.DoSomething; 
string name = func.Method.Name; 

편집 # 2 : 여기에 무슨 실현하기 위해 두 번째를해야 저를 아래로 표시 누구든지. 표현식 트리는 암시 적으로 람다 식과 함께 사용될 수 있으며 여기에서 특정 요청 정보를 얻는 가장 빠르고 안정적인 방법입니다.