Roslyn - Является ли реализация интерфейса символом?

Можно ли с помощью Roslyn узнать, является ли символ реализацией чего-либо в интерфейсе? Например Dispose() в IDisposable?

У меня есть символ, представляющий метод Dispose(), но, насколько я вижу, нет свойства, указывающего, что это реализация метода, определенного интерфейсом IDisposable.


person TWT    schedule 06.02.2017    source источник
comment
На самом деле это непросто и, в зависимости от вашей интерпретации, даже невозможно для публичных типов. Дополнительные сведения см. в исходном коде FindImplementedInterfaceMembersAsync< /а>. Обратите внимание на комментарий: метод может реализовывать метод интерфейса, даже если его содержащий тип не указывает, что он реализует интерфейс.   -  person Kris Vandermotten    schedule 13.02.2017


Ответы (2)


Конечно, это возможно.

Просто для вашего Dispose примера:

var disposeMethodSymbol = ...
var type = disposeMethodSymbol.ContainingType;
var isInterfaceImplementaton = type.FindImplementationForInterfaceMember(
            type.Interfaces.Single().
            GetMembers().OfType<IMethodSymbol>().Single()) == disposeMethodSymbol ;

Но если это для общего использования, вам нужно написать его в более общем виде, используйте AllInterfaces, а не Interfaces, и уж точно не используйте Single.

Пример:

public static bool IsInterfaceImplementation(this IMethodSymbol method)
{
    return method.ContainingType.AllInterfaces.SelectMany(@interface => @interface.GetMembers().OfType<IMethodSymbol>()).Any(interfaceMethod => method.ContainingType.FindImplementationForInterfaceMember(interfaceMethod).Equals(method));
}
person Dudi Keleti    schedule 06.02.2017
comment
Помните, что это не будет работать должным образом с универсальными интерфейсами. - person SLaks; 06.02.2017
comment
@SLaks, как мы можем позволить этому правильно работать и с универсальными интерфейсами? - person TWT; 28.11.2017

Вам может пригодиться этот набор методов расширения от Roslyn: http://sourceroslyn.io/#Microsoft.CodeAnalysis.Workspaces/ISymbolExtensions.cs,93

В частности, этот метод ExplicitOrImplicitInterfaceImplementations:

public static ImmutableArray<ISymbol> ExplicitOrImplicitInterfaceImplementations(this ISymbol symbol)
{
    if (symbol.Kind != SymbolKind.Method && symbol.Kind != SymbolKind.Property && symbol.Kind != SymbolKind.Event)
        return ImmutableArray<ISymbol>.Empty;

    var containingType = symbol.ContainingType;
    var query = from iface in containingType.AllInterfaces
                from interfaceMember in iface.GetMembers()
                let impl = containingType.FindImplementationForInterfaceMember(interfaceMember)
                where symbol.Equals(impl)
                select interfaceMember;
    return query.ToImmutableArray();
}
person SENya    schedule 30.11.2020
comment
В каком пакете/версии nuget существует этот метод? - person Sergey Zhukov; 04.08.2021
comment
Просто понял, что все эти расширения являются внутренними и не могут использоваться напрямую. - person Sergey Zhukov; 04.08.2021