Не удается получить явный элемент, реализованный в интерфейсе

Я использую 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();

Кто-нибудь знает, почему это происходит? Есть ли лучший способ работы с явно реализованными интерфейсами?

2 ответа

Решение

Похоже, вам нужно предоставить полную квалификацию подписи метода, когда она была явно реализована:

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

(Я собирался удалить этот вопрос, но я вижу, что кто-то отметил его как избранное, поэтому я предоставлю ответ, который работал для меня)

Используйте ITypeSymbol.FindImplementationForInterfaceMethod. Эти методы не должны быть найдены "по имени".

Другие вопросы по тегам