2011-09-24 7 views
2

내부 클래스의 공용 메서드가 어셈블리 외부에서 액세스 할 수있는 경우 중 하나는 메서드가 공용 메서드를 구현하거나 공용 기본 클래스에 정의 된 가상 메서드를 재정의하는 경우입니다.IMetadataImport 또는 MonoCecil에서 다른 어셈블리에서 내부 클래스의 메서드에 액세스 할 수 있는지 어떻게 알 수 있습니까?

IMetadataImport를 사용하면 특정 mdMethodDef의 경우인지 어떻게 알 수 있습니까?

업데이트 : 그 날이 IMetaDataImport에서 작업을 수행하는 방법을 알아내는 데 도움이 하듯이 나는 또한, Mono.Cecil에서이 작업을 수행하는 방법을 알고 싶습니다.

답변

3

: 여기

public interface ITest 
{ 
    void DoSomething(); 
} 

public class Test : ITest 
{ 
    public void DoSomething() 
    { 
    } 
} 

에서, Test 클래스가 성공적으로 C#을 사양에 정의 된대로 ITest 인터페이스를 구현을

(예를 13.4.2 Interface mapping에 대한)이 결과를 살펴보면 컴파일 된 어셈블리 코드 (도구와 같은 .NET 반사판 또는 ILDASM 등을 사용)이 표시됩니다

.method public hidebysig newslot virtual final instance void DoSomething() cil managed 
{ 
    .maxstack 8 
    L_0000: nop 
    L_0001: ret 
} 

그리고 ... 예 ... 테스트의 DoSomething 메서드와 ITest의 DoSomething 메서드를 관련시킬 어셈블리 메타 데이터에는 아무것도 없습니다. 보시다시피

Public Interface ITest 

    Sub DoSomething() 

End Interface 


Public Class Test 
    Implements ITest 


    Public Sub DoSomething() Implements ITest.DoSomething 

    End Sub 
End Class 

은, VB.NET, 당신은 명시 적으로 방법을 관계해야

VB.NET에서

, 당신은 확실히 그것을 컴파일 만들기 위해 Implements 키워드를 추가해야합니다, 다르다 당신이 IL은 VB.NET의 경우 어셈블리에서 생성 된 내용을 분석하면 인터페이스의 방법으로 클래스, 그리고, 당신은이를 찾을 수 있습니다 : 그래서

.method public newslot virtual final instance void DoSomething() cil managed 
{ 
    .override TestVB.ITest::DoSomething 
    .maxstack 8 
    L_0000: nop 
    L_0001: nop 
    L_0002: ret 
} 

, VB에서 컴파일 된 어셈블리, 정보가 C# - 컴파일 어셈블리와 함께 존재하지 않습니다. 언어에 따라 다릅니다. 실제로 CLR 엔진은 런타임에 매핑에 사용됩니다.

InterfaceMapping im = typeof(Test).GetInterfaceMap(typeof(ITest)); 

하지만 메타 데이터 만보고이 문제를 결정해야하는 경우, 해당 코드를 작성해야합니다 : 당신이 당신의 과정에서 어셈블리를 삽입 할 수있는 경우

,이 코드는 인터페이스 매핑을 확인하는 데 도움이 될 수 있습니다 당신 자신. 특히 제네릭을 사용하면 쉽지 않습니다. 또한 C#에서는 공용 메서드가 암시 적으로 여러 인터페이스를 구현할 수 있음을 잊지 마십시오. 도움이 될 수 있습니다

링크 : Mono.Cecil something like Type.GetInterfaceMap?

+0

당신이 제공 한 링크의 설명과 코드는 (Cecil의'GetOriginalBaseMethod' 메쏘드로 안내해주었습니다) 정확히 제가 필요로하는 것입니다. 고맙습니다. –

1

여기는 약간의 도움이되는 Cecil이 있습니다. 질문의 100 %는 다루지 않지만 이거나 약간의 추가 작업이 필요합니다. Gendarme 규칙

많은 방법 (또는 유형, 필드) 그래서 확장 방법, 에서 IsVisible가 필요한 검사 가장에 대처하기 위해 만들어졌습니다 가시성을 확인해야합니다. 그리고 에 의해 대부분 나는 (아직) 구현되지 않은 한 가지는 [InternalVisibleTo] 속성에 대한 지원이라는 것을 의미합니다. 방법에 대한

다른 파일은 세실 작업 할 때 유용 할 수 TypeDefinition 및 FieldDefinition과 다른 확장 방법의 많은에 대한 에서 IsVisible 확장 방법을 포함, MethodRocks.cs에서 찾습니다. 나는이 C#을 샘플 걸릴 경우

+0

내가 뭔가를 누락 될 수 있지만,이 코드는 내가 대해 요구하고있는 경우는 취급하지 않는 것 같다? 예를 들어, IsVisible이 MethodRef에서 System.OrdinalComparer.Equals (string, string)으로 호출되는 시나리오를 예로 들어 보겠습니다.이 메소드의 DeclaringType (OrdinalComparer)은 내부이므로 IsVisible은 false를 반환합니다. 물론이 메소드를 외부에서 행복하게 호출 할 수는 있습니다. mscorlib (StringComparer.Ordinal.Equals ("a", "b")')에 대한 참조가 StringComparer 인 경우 –

+0

추가 작업 없이는 작동하지 않습니다. * 모든 인터페이스를 일치 시키려면 */공개적으로 공개 할 수있는 기본 클래스 Gendarme (인터페이스, 기본 클래스, 메소드 매칭 등을 찾을 수있는 유사한 코드)은 빌딩 블록으로 사용할 수 있습니다.하지만 그대로 * 질문의 100 %를 커버합니다. – poupou