名称: dotnet-添加分析器 描述: “向项目添加分析器包。可为空、修剪、AOT兼容分析器、严重性配置。”
dotnet-添加分析器
向现有项目添加和配置.NET代码分析器。涵盖内置Roslyn CA规则、可为空引用类型强制执行、修剪/AOT兼容性分析器和第三方分析器包。
先决条件: 首先运行[技能:dotnet-版本检测] — 分析器功能因SDK版本而异。运行[技能:dotnet-项目分析]以了解当前项目布局。
范围
- 内置Roslyn CA规则和AnalysisLevel配置
- 可为空引用类型强制执行
- 修剪和AOT兼容性分析器
- 第三方分析器包和严重性配置
范围外
- EditorConfig层次结构和IDE代码样式首选项 — 参见[技能:dotnet-editorconfig]
- 解决方案布局和Directory.Build.props — 参见[技能:dotnet-项目结构]
- 带有分析器的新项目脚手架 — 参见[技能:dotnet-脚手架项目]
交叉参考: [技能:dotnet-项目结构]用于构建属性/目标的位置,[技能:dotnet-脚手架项目]包括新项目中的分析器设置,[技能:dotnet-editorconfig]用于EditorConfig层次结构/优先级、IDE代码样式首选项、命名规则和全局AnalyzerConfig文件。
内置Roslyn分析器
.NET SDK提供内置分析器,由AnalysisLevel控制。在Directory.Build.props中配置:
<PropertyGroup>
<AnalysisLevel>latest-all</AnalysisLevel>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
AnalysisLevel值
| 值 | 行为 |
|---|---|
latest |
仅默认规则 — 覆盖正确性,不覆盖样式 |
latest-minimum |
比默认更少的规则 |
latest-recommended |
默认 + 附加推荐规则 |
latest-all |
所有规则启用 — 最全面 |
9-all, 10-all |
固定到特定SDK版本的完整规则集 |
latest-all推荐用于新项目。对于有大量警告的现有项目,从latest-recommended开始并逐步收紧。
规则类别
| 类别 | 前缀 | 示例 |
|---|---|---|
| 设计 | CA1xxx | CA1002(不要暴露泛型列表)、CA1062(验证参数) |
| 全球化 | CA1300–CA1399 | CA1304(指定CultureInfo) |
| 性能 | CA1800–CA1899 | CA1822(标记成员为静态)、CA1848(使用LoggerMessage) |
| 可靠性 | CA2000–CA2099 | CA2000(释放对象)、CA2007(ConfigureAwait) |
| 安全 | CA2100–CA2199、CA3xxx、CA5xxx | CA2100(SQL注入)、CA3075(XML处理) |
| 用法 | CA2200–CA2299 | CA2211(非常量静态字段)、CA2245(不要分配给自身) |
| 命名 | CA1700–CA1799 | CA1707(标识符中无下划线) |
| 样式 | IDE0xxx | IDE0003(this限定)、IDE0063(using声明) |
EditorConfig严重性覆盖
在.editorconfig中按规则微调分析器严重性:
[*.cs]
# 抑制特定规则
dotnet_diagnostic.CA1062.severity = none # 可为空处理此规则
dotnet_diagnostic.CA2007.severity = none # 在ASP.NET Core应用中不需要
# 提升为错误
dotnet_diagnostic.CA1822.severity = error # 标记成员为静态
dotnet_diagnostic.CA1848.severity = warning # 使用LoggerMessage委托
# 样式强制执行
dotnet_diagnostic.IDE0005.severity = warning # 删除不必要的using
dotnet_diagnostic.IDE0063.severity = warning # 使用简单using语句
dotnet_diagnostic.IDE0090.severity = warning # 简化新表达式
按项目类型的常见抑制
ASP.NET Core应用 — 抑制ConfigureAwait警告:
dotnet_diagnostic.CA2007.severity = none
库 — 将CA2007保留为警告(调用者可能没有SynchronizationContext):
dotnet_diagnostic.CA2007.severity = warning
测试项目 — 放松某些规则:
dotnet_diagnostic.CA1707.severity = none # 允许测试名称中的下划线
dotnet_diagnostic.CA1062.severity = none # 参数由测试框架验证
dotnet_diagnostic.CA2007.severity = none # ConfigureAwait不相关
可为空引用类型
在Directory.Build.props中全局启用:
<PropertyGroup>
<Nullable>enable</Nullable>
</PropertyGroup>
可为空分析产生警告(CS86xx)而非CA规则。相关设置:
<PropertyGroup>
<!-- 将可为空警告视为错误 -->
<WarningsAsErrors>$(WarningsAsErrors);nullable</WarningsAsErrors>
</PropertyGroup>
对于现有代码库的逐步采用,按文件启用:
#nullable enable
参见[技能:dotnet-csharp-可为空引用类型]用于注解策略和模式。
修剪和AOT兼容性分析器
应用
对于使用修剪或Native AOT发布的应用,启用分析器以及发布属性:
<PropertyGroup>
<!-- 启用修剪发布 + 分析 -->
<PublishTrimmed>true</PublishTrimmed>
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>
<!-- 启用AOT发布 + 分析 -->
<PublishAot>true</PublishAot>
<EnableAotAnalyzer>true</EnableAotAnalyzer>
<!-- 单文件分析(修剪分析的子集) -->
<EnableSingleFileAnalyzer>true</EnableSingleFileAnalyzer>
</PropertyGroup>
尽早启用分析器(甚至在发布修剪之前)以在开发期间捕获问题。EnableTrimAnalyzer和EnableAotAnalyzer可以独立于PublishTrimmed/PublishAot设置。
库
库使用IsTrimmable和IsAotCompatible向消费者声明兼容性。即使消费者尚未启用修剪,也启用这些:
<PropertyGroup>
<IsTrimmable>true</IsTrimmable>
<IsAotCompatible>true</IsAotCompatible>
</PropertyGroup>
设置IsTrimmable/IsAotCompatible自动启用相应分析器。这确保当消费者最终启用修剪/AOT时,库能正常工作。
分析器标记的内容
这些分析器标记:
- 破坏修剪的反射用法(IL2xxx警告)
- 与AOT不兼容的P/Invoke模式
- 动态代码生成(
Reflection.Emit、System.Linq.Expressions编译) - 未用
[DynamicallyAccessedMembers]注解的类型
第三方分析器
通过Directory.Build.targets添加,以便应用于所有项目:
<!-- Directory.Build.targets -->
<Project>
<ItemGroup>
<PackageReference Include="Meziantou.Analyzer" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" PrivateAssets="all" />
</ItemGroup>
</Project>
使用CPM时,在Directory.Packages.props中添加版本条目:
<PackageVersion Include="Meziantou.Analyzer" Version="2.0.187" />
<PackageVersion Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.11.0-beta1.25058.1" />
推荐的分析器包
| 包 | 焦点 |
|---|---|
Meziantou.Analyzer |
安全、性能、最佳实践(广泛覆盖) |
Microsoft.CodeAnalysis.BannedApiAnalyzers |
通过BannedSymbols.txt禁止特定API |
Microsoft.CodeAnalysis.PublicApiAnalyzers |
跟踪公共API表面(库作者) |
SonarAnalyzer.CSharp |
安全、可靠性、可维护性 |
BannedSymbols.txt
使用BannedApiAnalyzers时,在仓库根目录创建BannedSymbols.txt并包含它:
<!-- Directory.Build.targets -->
<ItemGroup>
<AdditionalFiles Include="$(MSBuildThisFileDirectory)BannedSymbols.txt"
Condition="Exists('$(MSBuildThisFileDirectory)BannedSymbols.txt')" />
</ItemGroup>
示例BannedSymbols.txt:
T:System.DateTime;使用DateTimeOffset代替
M:System.DateTime.Now;使用DateTimeOffset.UtcNow代替
T:System.GC;不要直接调用GC方法
向现有项目添加分析器
- 启用内置分析器 — 在
Directory.Build.props中设置AnalysisLevel和EnforceCodeStyleInBuild - 从推荐级别开始 — 如果
latest-all产生过多警告,使用latest-recommended - 添加EditorConfig覆盖 — 抑制不适用于您项目类型的规则
- 添加第三方分析器 — 通过
Directory.Build.targets使用CPM版本 - 逐步修复 — 仅在解决现有警告后启用
TreatWarningsAsErrors,或使用<NoWarn>临时处理正在解决的类别
逐步采用模式
对于大型代码库,避免一次性修复所有警告:
<!-- Directory.Build.props — 迁移期间临时使用 -->
<PropertyGroup>
<AnalysisLevel>latest-recommended</AnalysisLevel>
<!-- 首先修复这些类别,然后删除NoWarn条目 -->
<NoWarn>$(NoWarn);CA1822;CA1848</NoWarn>
</PropertyGroup>
随着每个类别的解决,删除NoWarn条目。使用以下命令跟踪进度:
dotnet build 2>&1 | grep -oE 'CA[0-9]+' | sort | uniq -c | sort -rn