2009-12-26 2 views
1

다음과 같이 명시 적으로 구현 된 인터페이스 메서드를 나타내는 MethodInfo 개체가 있습니다.명시 적으로 구현 된 MethodInfo 객체가 참조하는 인터페이스를 어떻게 결정합니까?

MethodInfo GetMethod() 
{ 
    return typeof(List<>).GetMethod(
     "System.Collections.IEnumerable.GetEnumerator", 
     BindingFlags.Instance | BindingFlags.NonPublic); 
} 

어떻게 그것을 구현하는 인터페이스 유형을 취득하기 위해서이 MethodInfo 객체, System.Collections.IEnumerable를 나타내는 Type 객체를 조회 할 수 있습니까? InterfaceMapping 구조는 주어진 인터페이스를 구현하는 유형의 MethodInfo 객체를 가져 오는 역 동작을 제공하므로 작동하지 않습니다.

이 정보에 대한 메서드 이름을 명확하게 구문 분석 할 수있는 인위적인 예제입니다. 가능하다면이 일을 피하고 싶습니다.

답변

4

이 방법을 직접적으로 사용하는 방법을 모르겠다면 분명히 역순으로 InterfaceMapping을 사용할 수 있습니다. 메서드의 선언 형식에 의해 구현 된 모든 인터페이스를 반복하여 메서드가 해당 인터페이스의 인터페이스 맵에 있는지 확인합니다.

foreach (Type itf in method.DeclaringType.GetInterfaces()) 
{ 
    if (method.DeclaringType.GetInterfaceMap(itf).TargetMethods.Any(m => m == method)) 
    { 
    Console.WriteLine("match: " + itf.Name); 
    } 
} 

다소 비효율적 인 것처럼 보이지만, 대부분의 유형에서는 인터페이스가 거의 구현되지 않아 많은 문제가 발생하지 않습니다. 그것은 대단히 우아하지 않다는 것을 이해하십시오! 내 첫 번째 대답 죄송

+0

이것은 검색을 수행하는 유일한 방법 일 가능성이 높으며 단일 메서드로 구현되는 __all__ 인터페이스 메서드를 찾는 보너스가 추가되었습니다. –

0

시도 MethodInfo.DeclaringType.

+0

명시 적으로 구현 된 인터페이스 메소드에는 작동하지 않습니다. 인터페이스 유형을 구현하지 않고 인터페이스 메소드를 구현하는 유형을 리턴합니다. –

1

먼저 나는 InterfaceMap 구조를 통해 방법을 점점 시도하고 구조의 방법이 실제로 보고한다 DeclaringType와 인터페이스를 할에서. 그렇다면 나는 그걸로 꼼짝 못하고 MethodInfo을 얻기 위해 올린 방법을 사용하여 미묘하게 깨져 있다는 것을 깨닫지 못했습니다.

그러나 위와 같은 차이점은 인터페이스 메서드의 경우 MethodInfo이고 구현 메서드의 경우 MethodInfo은 실제로 같은 메서드가 아니라는 것을 알게되었습니다. 그리고 더 깊이 생각해 보면, 저는 여러분이하고 싶은 일이 믿을만하게하는 것이 불가능하다는 것을 실제로 확신합니다.

C#의 명시 적 인터페이스 구현은 CLR에서 실제로 작동하는 방식에 비해 약간의 구문 상 설탕입니다. 다른 언어에서는 하나의 구체적인 메소드가 구체적인 클래스가 여러 인터페이스 유형을 구현할 수있는 것과 같은 방법으로 여러 인터페이스 메소드를 구현할 수 있습니다. 예를 들어, VB.NET, 그것은이 일을 완벽하게 합법적이다 :

Public Overrides Function Baz() As String Implements IFoo.Foo, IBar.Bar 

을 여기에 명시 적으로 두 개의 인터페이스 메소드를 구현하는 것 한 가지 방법이있다. 원래의 인터페이스 클래스 또는 심지어 원래의 인터페이스 메소드를 얻을 수 있다면 어떤 것을 얻을 수 있습니까? 모호성을 어떻게 해결합니까?

저는 CLR 내부에 대한 전문가는 아니지만 인터페이스 맵이 일방적이라고 생각합니다. 암시 적으로 또는 명시 적으로 인터페이스 또는 메서드를 구현하면 컴파일러에서 인터페이스를 만들고 에서까지 구현하여 인터페이스에 대한 메서드 호출을 처리해야합니다.

C#으로 생성 된 메서드 이름을 거의 우연한 것으로 생각하십시오. 메소드 이름은 System.Collections.IEnumerable.GetEnumerator이지만 실제로는 이름 일 뿐이며 메소드 자체에 인코딩 된 System.Collections.IEnumerable에 대한 정보는 실제로 없습니다.

+0

설명해 주셔서 감사합니다. 또한 메서드가 명시 적으로 인터페이스 메서드에 매핑 할 때 이름이 아닌 서명 만 일치해야한다고 지적했습니다. –