您可以使用Roslyn Code Analyzer做到这一点。以下代码将创建一个DiagnosticAnalyzer
,如果使用String.EndsWith()
,将会发出编译器警告。
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class ForbiddenMethodsAnalyzer : DiagnosticAnalyzer
{
private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor("Forbidden",
"Don't use this method!",
"Use of the '{0}' method is not allowed",
"Forbidden.Stuff",
DiagnosticSeverity.Warning,
isEnabledByDefault: true,
description: "This method is forbidden");
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(Rule); } }
public override void Initialize(AnalysisContext context)
{
context.RegisterSyntaxNodeAction(AnalyzeSyntaxNode, SyntaxKind.InvocationExpression);
}
private static void AnalyzeSyntaxNode(SyntaxNodeAnalysisContext context)
{
var invocationExpression = (InvocationExpressionSyntax)context.Node;
var memberAccessExpression = invocationExpression.Expression as MemberAccessExpressionSyntax;
if (memberAccessExpression?.Name.ToString() == "EndsWith")
{
var memberSymbol = context.SemanticModel.GetSymbolInfo(memberAccessExpression).Symbol as IMethodSymbol;
var containingType = memberSymbol.ContainingType;
if (containingType.ContainingNamespace.Name == "System" && containingType.Name == "String")
{
var diagnostic = Diagnostic.Create(Rule, invocationExpression.GetLocation(), memberAccessExpression.ToString());
context.ReportDiagnostic(diagnostic);
}
}
}
}
有3个选项,使用分析是这样的:
- 直接添加
DiagnosticAnalyzer
代码到您的项目。它将仅适用于该解决方案。
- 创建一个 类库,其中包含
DiagnosticAnalyzer
,并将其作为Nuget包分发给 。它仅适用于使用该软件包的解决方案。
- 编译包含 类的完整VSIX扩展。分析仪可以在您加载的任何解决方案上工作。
这是我使用Roslyn代码分析功能所做的第一个项目,所以很不幸我不明白这里发生的一切。我开始使用默认的分析模板,并尝试了各种方法,遍历代码,并使用监视窗口查看变量,直到找到所需的信息为止。
基本过程是注册一个SyntaxNode分析函数,过滤到调用方法的表达式。在该方法中,我检查MemberAccessExpressionSyntax
的Name
是否是“EndsWith”。如果是,则获取方法处于打开状态的ContainingType
,然后检查它是否位于System
命名空间的String
类中。如果是这样,我从DiagnosticDescriptor
创建一个Diagnostic
实例来告诉IDE问题出在哪里以及它代表了多少问题(在这种情况下有一个警告,如果我愿意,可以将它设置为一个完整的错误,这将防止来自编译的代码)。也可以向用户提供不同的选项来自动修复错误,但我还没有探究过。
很多信息来自this tutorial,以及大量的试验和错误。
它是否在您可以安全忽略的名称空间中? –
@ DanielA.White是的,但我只想忽略扩展方法,不是整个DLL或命名空间 – yey
链接的问题是否真的重复?这个问题是关于在你自己的程序集中标记一个你控制的方法。这个问题是关于在第三方程序集中标记的,你无法控制。我已投票重新开放。 –