.NET 源代码分析概述

.NET Compiler Platform (Roslyn) 分析器会检查 C# 或 Visual Basic 代码的代码质量和样式问题。 从 .NET 5 开始,这些分析器包含在 .NET SDK 中,无需单独安装。 如果项目面向 .NET 5 或更高版本,则默认启用代码分析。 如果项目面向不同的 .NET 实现(例如 .NET Core、.NET Standard 或 .NET Framework),则必须通过将 EnableNETAnalyzers 属性设置为 true 以手动启用代码分析。

如果你不想移动到 .NET 5+ SDK、具有非 SDK 样式的 .NET Framework 项目或更倾向于使用基于 NuGet 包的模型,则也可以在 Microsoft.CodeAnalysis.NetAnalyzers NuGet 包中使用该分析器。 对于按需版本更新,你可能更倾向于使用基于包的模型。

注意

.NET 分析器与目标框架无关。 即,你的项目不需要面向特定的 .NET 实现。 分析器适用于面向 .NET 5+ 及更早 .NET 版本(如 .NET Core 3.1 和 .NET Framework 4.7.2)的项目。 但是,若要使用 EnableNETAnalyzers 属性启用代码分析,则项目必须引用项目 SDK

如果分析器发现规则冲突,则这些冲突会被报告为建议、警告或错误,具体取决于每个规则的配置方式。 代码分析冲突以前缀“CA”或“IDE”显示,以便将它们与编译器错误区分开来。

代码质量分析

代码质量分析(“CAxxxx”)规则检查 C# 或 Visual Basic 代码的安全性、性能、设计及其他问题。 分析功能针对面向 .NET 5 或更高版本的项目默认启用。 可通过将 EnableNETAnalyzers 属性设置为 true,在面向 .NET 早期版本的项目上启用代码分析。 你也可通过将 EnableNETAnalyzers 设置为 false,对项目禁用代码分析。

提示

如果使用的是 Visual Studio,则许多分析器规则都有相关的代码修补程序,可以应用它们来纠正问题。 代码修补程序显示在灯泡图标菜单中。

已启用的规则

默认情况下,将启用以下规则作为 .NET 9 中的错误或警告。 其他规则作为建议启用。

诊断 ID 类别 Severity 新增的版本 说明
CA1416 互操作性 警告 .NET 5 验证平台兼容性
CA1417 互操作性 警告 .NET 5 请勿对 P/Invokes 的字符串参数使用 OutAttribute
CA1418 互操作性 警告 .NET 6 使用有效的平台字符串
CA1420 互操作性 警告 .NET 7 在禁用后使用需要运行时封送的功能将导致运行时异常
CA1422 互操作性 警告 .NET 7 验证平台兼容性
CA1831 性能 警告 .NET 5 在合适的情况下,对字符串使用 AsSpan 而不是基于范围的索引器
CA1856 性能 错误 .NET 8 ConstantExpected 属性的用法不正确
CA1857 性能 警告 .NET 8 参数需要常数
CA2013 可靠性 警告 .NET 5 请勿将 ReferenceEquals 与值类型结合使用
CA2014 可靠性 警告 .NET 5 请勿在循环中使用 stackalloc
CA2015 可靠性 警告 .NET 5 请勿为派生自 MemoryManager<T> 的类型定义终结器
CA2017 可靠性 警告 .NET 6 参数计数不匹配
CA2018 可靠性 警告 .NET 6 Buffer.BlockCopycount 参数应指定要复制的字节数
CA2021 可靠性 警告 .NET 8 请勿使用不兼容类型调用 Enumerable.Cast<T>Enumerable.OfType<T>
CA2022 可靠性 警告 .NET 9 避免使用 读取不精确 Stream.Read
CA2200 使用情况 警告 .NET 5 再次引发以保留堆栈详细信息
CA2247 使用情况 警告 .NET 5 传递到 TaskCompletionSource 构造函数的参数应为 TaskCreationOptions 枚举,而不是 TaskContinuationOptions
CA2252 使用情况 错误 .NET 6 选择预览功能
CA2255 使用情况 警告 .NET 6 不应在库中使用 ModuleInitializer 属性
CA2256 使用情况 警告 .NET 6 在父接口中声明的所有成员必须在 DynamicInterfaceCastableImplementation 特性的接口中具有实现
CA2257 使用情况 警告 .NET 6 使用 DynamicInterfaceCastableImplementationAttribute 在接口上定义的成员应为 static
CA2258 使用情况 警告 .NET 6 不支持在 Visual Basic 中提供 DynamicInterfaceCastableImplementation 接口
CA2259 使用情况 警告 .NET 7 ThreadStatic 仅影响静态字段
CA2260 使用情况 警告 .NET 7 使用正确的类型参数
CA2261 使用情况 警告 .NET 8 请勿将 ConfigureAwaitOptions.SuppressThrowingTask<TResult> 搭配使用
CA2264 使用情况 警告 .NET 9 不要将不可为 null 的值传递给 ArgumentNullException.ThrowIfNull
CA2265 使用情况 警告 .NET 9 请勿与Span<T>nulldefault

可更改这些规则的严重性,以禁用这些规则或将它们提升为错误。 也可启用更多规则

启用其他规则

分析模式指预定义的代码分析配置,在此配置下,未启用任何规则、启用某些规则或启用所有规则。 在默认分析模式 (Default) 下,只有少量规则作为生成警告启用。 可通过在项目文件中设置 <AnalysisMode> 属性来更改项目的分析模式。 允许的值为:

说明
None 所有规则都处于禁用状态。 可以选择选择加入各条规则,以启用它们。
Default 默认模式是指某些规则作为生成警告启用;在该模式下,某些规则作为 Visual Studio IDE 建议启用,其余规则被禁用。
Minimum Default 模式更主动的模式。 强烈建议生成实施的某些建议作为生成警告启用。 若要查看其中包含的规则,请检查 %ProgramFiles%/dotnet/sdk/[version]/Sdks/Microsoft.NET.Sdk/analyzers/build/config/analysislevel_[level]_minimum.editorconfig 文件。
Recommended Minimum 模式更主动的模式,其中启用了更多规则作为生成警告。 若要查看其中包含的规则,请检查 %ProgramFiles%/dotnet/sdk/[version]/Sdks/Microsoft.NET.Sdk/analyzers/build/config/analysislevel_[level]_recommended.editorconfig 文件。
All 所有规则作为生成警告启用*。 可以选择选择退出各条规则,以禁用它们。

* 如果将 AnalysisMode 设置为 All,或者将 AnalysisLevel 设置为 latest-all,以下规则将不会启用:CA1017、CA1045、CA1005、CA1014、CA1060、CA1021 和代码指标分析器规则(CA1501、CA1502、CA1505、CA1506 和 CA1509)。 将来的版本可能会弃用这些旧规则。 但是,这些规则仍然可以通过使用 dotnet_diagnostic.CAxxxx.severity = <severity> 条目来单独启用。

还可以省略 <AnalysisMode> 属性的 <AnalysisLevel> 复合值。 例如,以下值为最新版本实现推荐的一组规则:<AnalysisLevel>latest-Recommended</AnalysisLevel>。 有关详细信息,请参阅 AnalysisLevel

若要查找每个可用规则的默认严重性以及了解规则是否在 Default 分析模式下启用,请参阅完整规则列表

视警告为错误

如果在生成项目时使用 -warnaserror 标志,则所有代码分析警告也会被视为错误。 如果不希望在出现 -warnaserror 时将代码质量警告 (CAxxxx) 视为错误,可在项目文件中将 CodeAnalysisTreatWarningsAsErrors MSBuild 属性设置为 false

<PropertyGroup>
  <CodeAnalysisTreatWarningsAsErrors>false</CodeAnalysisTreatWarningsAsErrors>
</PropertyGroup>

你仍会看到任何代码分析警告,但它们不会中断生成。

最新更新

默认情况下,在升级到较新版本的 .NET SDK 时,你将获得最新的代码分析规则和默认规则严重性。 如果你不希望出现此行为(例如,如果你想要确保未启用或禁用任何新规则),可通过以下方式之一来替代此行为:

  • AnalysisLevel MSBuild 属性设置为特定值,以将警告锁定到相应的集。 在升级到较新的 SDK 时,你仍会获得针对这些警告的 bug 修补程序,但系统不会启用新的警告,也不会禁用现有的警告。 例如,若要将规则集锁定到 .NET SDK 版本 8.0 附带的规则集,请将以下条目添加到项目文件。

    <PropertyGroup>
      <AnalysisLevel>8.0</AnalysisLevel>
    </PropertyGroup>
    

    提示

    AnalysisLevel 属性的默认值为 latest,这意味着在你移动到较新版本的 .NET SDK 时,你始终会获得最新的代码分析规则。

    如需了解详细信息,以及查看可能值的列表,请参阅AnalysisLevel

  • 安装 Microsoft.CodeAnalysis.NetAnalyzers NuGet 包,将规则更新与 .NET SDK 更新分离。 对于面向 .NET 5+ 的项目,安装该包将关闭内置 SDK 分析器。 如果 SDK 所含的分析器程序集版本比 NuGet 包所含的版本更新,你会收到生成警告。 若要禁用该警告,请将 _SkipUpgradeNetAnalyzersNuGetWarning 属性设置为 true

    注意

    如果你安装了 Microsoft.CodeAnalysis.NetAnalyzers NuGet 包,则不应将 EnableNETAnalyzers 属性添加到项目文件或 Directory.Build.props 文件。 在安装了 NuGet 包并将 EnableNETAnalyzers 属性设置为 true 时,一个生成警告随即生成。

代码样式分析

通过代码样式分析(“IDExxxx”)规则,可在代码库中定义和维护一致的代码样式。 默认的启用设置为:

  • 命令行生成:默认情况下,命令行生成上所有 .NET 项目的代码样式分析处于禁用状态。

    可以在 命令行和 Visual Studio 内部的生成上启用代码样式分析。 代码样式冲突显示为带有“IDE”前缀的警告或错误。 这使你能够在生成时强制执行一致的代码样式。

  • Visual Studio:默认情况下,Visual Studio 中的所有 .NET 项目都启用了代码样式分析,即代码重构快速操作

有关代码样式分析规则的完整列表,请参阅代码样式规则

生成时启用

可以在从命令行和 Visual Studio 中生成时启用代码样式分析。 (然而,出于性能方面的原因,一些代码样式规则仍仅适用于 Visual Studio IDE。)

执行以下步骤,在生成时启用代码样式分析:

  1. 将 MSBuild 属性 EnforceCodeStyleInBuild 设置为 true

  2. 在 .editorconfig 文件中,配置你希望在生成时作为警告或错误运行的每个“IDE”代码样式规则。 例如:

    [*.{cs,vb}]
    # IDE0040: Accessibility modifiers required (escalated to a build warning)
    dotnet_diagnostic.IDE0040.severity = warning
    

    提示

    从 .NET 9 开始,还可以使用选项格式 指定严重性,并在生成时考虑它。 例如:

    [*.{cs,vb}]
    # IDE0040: Accessibility modifiers required (escalated to a build warning)
    dotnet_style_require_accessibility_modifiers = always:warning
    

    或者,可将整个类别默认配置为警告或错误,然后选择性地禁用该类别中你不希望在生成时运行的规则。 例如:

    [*.{cs,vb}]
    
    # Default severity for analyzer diagnostics with category 'Style' (escalated to build warnings)
    dotnet_analyzer_diagnostic.category-Style.severity = warning
    
    # IDE0040: Accessibility modifiers required (disabled on build)
    dotnet_diagnostic.IDE0040.severity = silent
    

抑制警告

一种抑制规则冲突的方法是在 EditorConfig 文件中将该规则 ID 的严重性选项设置为 none。 例如:

dotnet_diagnostic.CA1822.severity = none

有关抑制警告的详细信息和其他方式,请参阅如何抑制代码分析警告

第三方分析器

除了官方 .NET 分析器外,你也可以安装第三方分析器,如 StyleCopRoslynatorXUnit AnalyzersSonar Analyzer

另请参阅