.NET Analyzers自定义规则编写方法咨询
.NET Analyzers自定义规则完全可行!看这篇就够了
当然可行!.NET Analyzers本身就支持自定义规则开发,和你之前自己写的自定义规则DLL思路相通,只不过需要遵循Roslyn分析器的规范来实现。下面我一步步给你讲具体怎么操作:
一、先搞定开发环境
- 确保你用的是Visual Studio 2022(或者2019更到最新版本),新版本对Roslyn分析器的开发支持更顺手
- 安装「.NET Compiler Platform SDK」工作负载:打开Visual Studio安装器,切换到「单个组件」标签,找到这个选项勾选安装就行
二、创建自定义分析器项目
- 打开VS,新建项目,直接搜索「Analyzer with Code Fix (.NET Standard)」这个模板,选它创建项目
- 这个模板自带了一个示例分析器和对应的代码修复,你可以直接基于这个模板改造成自己的规则,省得从头搭架子
三、编写你的自定义规则
1. 核心分析器类实现
你需要写一个继承自DiagnosticAnalyzer的类,定义你的规则元数据,然后实现分析逻辑:
- 用
DiagnosticAnalyzerAttribute指定支持的语言(比如C#、VB) - 重写
SupportedDiagnostics属性,定义规则的ID、标题、描述、类别、严重级别这些信息 - 重写
Initialize方法,注册你要监听的语法/语义节点,然后在回调里写规则判断逻辑
给你个简单的示例片段,比如检测调用过时方法的规则:
[DiagnosticAnalyzer(LanguageNames.CSharp)] public class ObsoleteMethodAnalyzer : DiagnosticAnalyzer { // 自定义规则ID,最好有辨识度 public const string DiagnosticId = "CustomRule001"; // 用资源文件管理多语言文本,模板里自带Resources.resx,直接用就行 private static readonly LocalizableString Title = new LocalizableResourceString(nameof(Resources.AnalyzerTitle), Resources.ResourceManager, typeof(Resources)); private static readonly LocalizableString MessageFormat = new LocalizableResourceString(nameof(Resources.AnalyzerMessageFormat), Resources.ResourceManager, typeof(Resources)); private static readonly LocalizableString Description = new LocalizableResourceString(nameof(Resources.AnalyzerDescription), Resources.ResourceManager, typeof(Resources)); private const string Category = "Usage"; // 定义诊断规则的描述符 private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor( DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Warning, isEnabledByDefault: true, description: Description); public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule); public override void Initialize(AnalysisContext context) { // 配置分析器的行为,比如不分析生成的代码,允许并行执行提升性能 context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); context.EnableConcurrentExecution(); // 注册监听方法调用的语法节点,这里指定监听InvocationExpression context.RegisterSyntaxNodeAction(AnalyzeInvocationNode, SyntaxKind.InvocationExpression); } private void AnalyzeInvocationNode(SyntaxNodeAnalysisContext context) { var invocationExpr = (InvocationExpressionSyntax)context.Node; // 通过语义模型获取方法的符号信息 var methodSymbol = context.SemanticModel.GetSymbolInfo(invocationExpr).Symbol as IMethodSymbol; // 这里写你的规则逻辑:如果调用的方法是"ObsoleteMethod",就触发诊断 if (methodSymbol?.Name == "ObsoleteMethod") { var diagnostic = Diagnostic.Create(Rule, invocationExpr.GetLocation()); context.ReportDiagnostic(diagnostic); } } }
2. (可选)加代码修复功能
如果你的规则需要提供自动修复(比如替换过时方法为新方法),可以写一个继承自CodeFixProvider的类,实现修复逻辑。模板里也有示例,你照着改就行。
四、测试你的分析器
- 模板自带了测试项目,你可以写单元测试验证规则是否能正确触发
- 也可以直接调试:把分析器项目设为启动项目,调试时会打开一个新的VS实例,在里面建个测试项目,你的分析器会自动加载,马上就能看到效果
五、部署到你的项目里用
编译分析器项目后,生成的DLL就是你的自定义规则,有两种方式用:
- NuGet包方式(推荐):把分析器打包成NuGet包,团队里的项目直接安装就行,方便共享和更新
- 直接引用方式:在目标项目里添加对分析器DLL的引用,然后在项目文件里加这段配置:
<ItemGroup> <Reference Include="YourCustomAnalyzer.dll"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </Reference> </ItemGroup>
小提示
- 自定义分析器基于Roslyn API,建议先了解下Roslyn的语法树、语义分析这些基础概念,写起来更顺手
- 分析逻辑尽量轻量化,避免耗时操作,
EnableConcurrentExecution()能让分析器并行执行,提升性能 - 可以参考官方的Roslyn分析器示例,学习更复杂的规则写法
内容的提问来源于stack exchange,提问作者Lance
相关产品推荐
相关产品推荐

