如何在接口中检查功能,而这些接口又继承自标记接口?
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();
}
我如何检查所有接口的函数签名(甚至可能是实现这些接口的 类 和继承自实现 类 的 类,但现在这是次要的)从标记接口 ISomethingRoot1
和 ISomethingRoot2
继承?我看到至少有一个问题与此 有关,但我还没有掌握它的窍门。看起来我应该注册到 SymbolKind.NamedType
操作,但是 AnalyzeSymbol
部分看起来如何找到继承自 ISomethingRoot1
和 ISomethingRoot2
的函数签名?
这是我目前正在做的一些代码,以使问题更清楚:
[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()
.
获取成员
关于定义 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();
}
我如何检查所有接口的函数签名(甚至可能是实现这些接口的 类 和继承自实现 类 的 类,但现在这是次要的)从标记接口 ISomethingRoot1
和 ISomethingRoot2
继承?我看到至少有一个问题与此 SymbolKind.NamedType
操作,但是 AnalyzeSymbol
部分看起来如何找到继承自 ISomethingRoot1
和 ISomethingRoot2
的函数签名?
这是我目前正在做的一些代码,以使问题更清楚:
[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()
.