如何在接口中检查功能,而这些接口又继承自标记接口?

How does one check functions in interfaces that in turn inherit from marker interfaces?

关于定义 Roslyn Analyzer 规则的学习经验,假设我定义了如下接口

//These are a marker interfaces.
public interface ISomethingRoot1 {}
public interface ISomethingRoot2 {}

public interface ISomething: ISomethingRoot1
{
    int SomeOperation();    
}

public interface ISomething2: ISomethingRoot2
{
    int SomeOperation2();
}

我如何检查所有接口的函数签名(甚至可能是实现这些接口的 类 和继承自实现 类 的 类,但现在这是次要的)从标记接口 ISomethingRoot1ISomethingRoot2 继承?我看到至少有一个问题与此 有关,但我还没有掌握它的窍门。看起来我应该注册到 SymbolKind.NamedType 操作,但是 AnalyzeSymbol 部分看起来如何找到继承自 ISomethingRoot1ISomethingRoot2 的函数签名?

这是我目前正在做的一些代码,以使问题更清楚:

[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]
public class PublicInterfaceAnalyzer: DiagnosticAnalyzer
{               
    private static ImmutableArray<DiagnosticDescriptor> SupportedRules { get; } = 
        new ImmutableArray<DiagnosticsDescriptor>(new DiagnosticDescriptor(id: "CheckId1",
            title: "Check1",
            messageFormat: "Placeholder text",
            category: "Usage",
            defaultSeverity: DiagnosticSeverity.Warning,
            isEnabledByDefault: true));

    public override void Initialize(AnalysisContext context)
    {
        context.RegisterSymbolAction(AnalyzeSymbol, SymbolKind.NamedType);
    }

    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => SupportedRules;


    private void AnalyzeSymbol(SymbolAnalysisContext context)
    {                     
        //How to check that the functions have, say, a certain kind of
        //of a return value or parameters or naming? I think I know how
        //to do that, but I'm not sure how to get a hold of the correct
        //interfaces and have a collection or their (public) methods to check.

        //This could be one way to go, but then in Initialize
        //should be "SymbolKind.Method", would that be the route to take?
        //The following omits the code to get the interfaces and do some
        //of the checks as this is code in progress and the main problem
        //is getting hold of the function signatures of interfaces that  
        //inherit from the marker interfaces.
        var symbol = (IMethodSymbol)context.Symbol;                                   
        context.ReportDiagnostic(Diagnostic.Create(SupportedRules[0], symbol.Locations[0], symbol.Name));          
    }                                        
}

您可以通过以下方式获取对标记界面的引用:

var marker1 = context.SemanticModel.Compilation.GetTypeByMetadataName("NS.ISomethingRoot1");

然后如果你在 SymbolAction for NamedTypes,你可以检查当前处理的符号是否实现这个 marker1 或不:

var symbol = context.Symbol as INamedTypeSymbol;
var implements = symbol.AllInterfaces.Any(@interface => @interface.Equals(marker1));

然后你可以做任何你想检查类型成员的事情。您可以通过调用 symbol.GetMembers().

获取成员