2014-06-05 7 views
3

Roslyn을 사용하여 C# 코드를 분석하고 명시 적으로 구현 된 인터페이스를 가지고 놀 때 문제가 발생했습니다. 인터페이스를 구현하는 유형이 주어지면 명시 적으로 구현 된 멤버를 이름으로 검색 할 수 없습니다. 예를 들면 다음과 같습니다.명시 적 인터페이스 구현 멤버를 가져올 수 없습니다.

var tree = CSharpSyntaxTree.ParseText(@" 
using System; 

namespace ConsoleApplication1 
{ 
    class MyClass : IDisposable 
    { 
     void IDisposable.Dispose() 
     { 
     } 
     public void Dispose() 
     { 
     } 
    } 
}"); 

var Mscorlib = new MetadataFileReference(typeof(object).Assembly.Location); 
var compilation = CSharpCompilation.Create("MyCompilation", 
    syntaxTrees: new[] { tree }, references: new[] { Mscorlib }); 
var model = compilation.GetSemanticModel(tree); 

var myType = compilation.GetTypeByMetadataName("ConsoleApplication1.MyClass"); 
var dispose = myType.GetMembers("Dispose").SingleOrDefault(); 
//explicitDispose is null. 
var explicitDispose = myType.GetMembers("IDisposable.Dispose").SingleOrDefault(); 

이 경우는 네임 스페이스 내에있는 경우에만 해당되며 다음 코드가 제대로 작동합니다.

var tree = CSharpSyntaxTree.ParseText(@" 
class MyClass : IDisposable 
{ 
    void IDisposable.Dispose() 
    { 
    } 
    public void Dispose() 
    { 
    } 
}"); 
var Mscorlib = new MetadataFileReference(typeof(object).Assembly.Location); 
var compilation = CSharpCompilation.Create("MyCompilation", 
    syntaxTrees: new[] { tree }, references: new[] { Mscorlib }); 
var model = compilation.GetSemanticModel(tree); 

var myType = compilation.GetTypeByMetadataName("MyClass"); 
var dispose = myType.GetMembers("Dispose").SingleOrDefault(); 
//explicitDispose is not null. 
var explicitDispose = myType.GetMembers("IDisposable.Dispose").SingleOrDefault(); 

왜 이런 일이 발생하는지 알고 있습니까? 명시 적으로 구현 된 인터페이스로 작업하는 더 좋은 방법이 있습니까?

답변

6

이 명시 적으로 구현 된 때 완전한 방법 서명을 제공 할 필요가 나타납니다

var explicitDispose = myType.GetMembers("System.IDisposable.Dispose").SingleOrDefault(); 

(나는이 질문을 삭제하려고했지만, 그래서, 누군가가 좋아하는로 표시 한 참조

+3

자신 만의 질문에 답하는 데 아무런 해가 없습니다. 스택 오버 플로우의 절반 정도가 다음 사람이 궁금해하는 답변의 원천입니다! –

2

ITypeSymbol.FindImplementationForInterfaceMethod을 사용하십시오. 이 방법들은 "이름으로"찾을 수있는 것이 아닙니다.

+0

사실,이 단계는 FindImplementationForInterface()를 사용하기 전에 수행되었습니다. 문제는 올바른 인터페이스 멤버를 전달해야했습니다. 그래서 먼저 인터페이스에서 해당 멤버를 찾아야했습니다. 기본적으로 MyClass.System.IDisposable.Dispose() => System.IDisposable.Dispose()에서 이동하려고합니다. – JoshVarty

+0

즉, 구체적인 방법이 주어진다면 어떤 인터페이스가 정의되어 있는지 찾으려고합니다. 그것이 하나에서 정의 된 경우). – JoshVarty

+0

메서드가 둘 이상의 인터페이스 메서드를 구현할 수 있으므로 찾고있는 답변이 고유하지 않습니다. 해당 이름의 모든 구현 된 인터페이스 메소드를 반복하고 구현이 자신의 메소드인지 확인하십시오. –