您可以使用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
鏈接的問題是否真的重複?這個問題是關於在你自己的程序集中標記一個你控制的方法。這個問題是關於在第三方程序集中標記的,你無法控制。我已投票重新開放。 –