抑制代码分析违规

如果在创建代码时与团队协作,则表明警告不适用通常很有用。 通过抑制代码分析违反项,表明给团队成员代码已被审阅,并且可以抑制警告。 以下部分介绍了使用 Visual Studio IDE 取消代码分析冲突的不同方法。

使用 EditorConfig 文件抑制违规

在解决方案或项目的 EditorConfig 文件中,为要配置的每个规则添加一个条目,并将其严重性 none设置为 。 例如,dotnet_diagnostic.CA1822.severity = none。 有关详细信息,请参阅 EditorConfig 文件中手动配置规则严重性。 若要添加 EditorConfig 文件,请参阅 向项目添加 EditorConfig 文件

抑制源代码中的违规

可以使用预处理器指令禁止源代码中的冲突,从而禁止特定代码行的冲突:

或者,可以使用 SuppressMessageAttribute 属性 取消 C# 和 Visual Basic 代码中的警告。

使用代码编辑器抑制违规

若要使用代码编辑器取消冲突,请执行以下步骤:

  1. 将光标置于具有冲突的代码行中,然后按 Ctrl+Period (.)Alt+Enter 以打开 “快速作” 菜单。

  2. 选择 “抑制或配置问题”>抑制<规则编号>,然后选择 “在源中”“在源(属性)中”

    • 如果在 Source 中选择,则会看到添加到代码中的预处理器指令的预览。

      在“快速操作抑制”菜单中选择“源”时显示的屏幕截图。

    • 如果在 Source (attribute) 中选择,则会看到添加到代码的 SuppressMessageAttribute 属性 的预览。

      在“快速动作抑制”菜单中选择“源”(属性)的屏幕截图。

使用错误列表抑制违规事项

若要使用 “错误列表” 窗口取消冲突,请执行以下步骤:

  1. 从“ 错误列表 ”窗口中,选择要取消的规则。

  2. 右键单击,然后选择禁止显示>在源中

    此时将打开“预览更改”对话框,并显示 C# #pragma 警告指令 或添加到源代码中的 Visual Basic #Disable 警告指令的预览。

    显示用于在代码文件中添加 #pragma 警告的“预览更改”对话框的屏幕截图。

  3. 选择 “应用” 以保存对代码文件的更改。

排除错误列表生成诊断

如果在“错误列表”窗口中看不到“禁止显示”菜单选项,则冲突可能是来自生成而不是实时分析。 “ 错误列表 ”窗口显示实时代码分析和生成中的诊断或规则冲突。 例如,由于生成诊断可能已过时,因此,如果已编辑代码以修复冲突但未重新生成冲突,则无法始终从 错误列表中取消这些诊断。

实时分析或 IntelliSense 的诊断始终与当前源 up-to日期,并且始终可以从 错误列表中取消诊断。 若要从选择中排除构建诊断,请执行以下步骤:

  1. Error List 源过滤器下拉列表中,将选择从 Build + IntelliSense 更改为 IntelliSense Only

    显示错误列表源筛选器的屏幕截图。

  2. 选择要取消的诊断,并按前面所述继续。

使用全局抑制文件抑制违规

全局抑制文件使用 SuppressMessageAttribute 属性来抑制代码冲突。

使用代码编辑器中的全局抑制文件

若要使用代码编辑器通过全局抑制文件来抑制违规,请执行以下步骤:

  1. 在代码编辑器中,将光标置于具有冲突的代码行上,然后按 Ctrl+Period (.)Alt+Enter 打开 “快速作” 菜单。

  2. 选择 “禁止显示 <规则编号>”,然后在 “抑制文件”中选择

    Visual Studio 在代码编辑器中创建一个选项卡,其中包含新的全局抑制文件。

使用错误列表中的全局抑制文件

若要使用全局抑制文件通过 “错误列表” 窗口抑制违规行为,请执行以下步骤:

  1. 从“ 错误列表 ”窗口中,选择要取消的规则。

  2. 右键单击,然后选择“抑制>在抑制文件中”。

    打开“预览更改”对话框,并显示全局抑制文件中添加的SuppressMessageAttribute属性的预览。

    显示抑制文件中具有 SuppressMessageAttribute 属性的“预览更改”对话框的屏幕截图。

  3. 选择 “应用” 以保存全局抑制文件。

消除所有当前违反

抑制所有当前违规有时称为基线。 若要取消解决方案或项目中的所有当前冲突,请执行以下步骤:

  1. 在 Visual Studio 菜单栏中,选择 分析>生成解决方案并抑制活动问题

  2. 选择 针对解决方案 以抑制整个解决方案的违规行为,或选择 针对 <项目名称> 以仅抑制项目的违规行为。

使用项目设置抑制违规事项

若要使用解决方案资源管理器项目设置取消冲突,请执行以下步骤:

  1. 解决方案资源管理器中,选择项目。

  2. 右键单击,然后选择“ 属性 ”(或按 Alt + Enter)。

  3. “属性” 窗口中,从左窗格中选择 “代码分析 ”,然后清除 生成的代码中的“禁止显示结果”。

使用规则集抑制违规

在规则集编辑器中,清除其名称旁边的复选框,或将 “作 ”设置为 “无”。

源内抑制和 SuppressMessageAttribute 属性

源内抑制 (ISS) 使用 SuppressMessageAttribute 属性来禁止显示警告。 可以将属性 SuppressMessageAttribute 添加到生成警告的代码段附近的源文件。

可以在代码编辑器中手动输入属性,也可以按如下所示自动添加属性:

  1. 在代码编辑器中,将光标置于具有冲突的代码行上,然后按 Ctrl+Period (.)Alt+Enter 打开 “快速作” 菜单。

  2. 从“快速操作”菜单中选择“抑制或配置问题”抑制规则编号<>。>

  3. 执行以下步骤之一:

    • 在源(属性)中选择

      Visual Studio 向代码添加属性 SuppressMessageAttribute

    • 在抑制文件中选择。

      Visual Studio 在代码编辑器中创建一个选项卡,其中包含具有 SuppressMessageAttribute 属性的新全局抑制文件。

SuppressMessageAttribute 属性是一个条件属性,包含在托管代码程序集的元数据中。 仅当编译期间定义了CODE_ANALYSIS编译符号时,才包含此属性。

仅在 C++ 和 CLI 代码中,在头文件中使用宏 CA_SUPPRESS_MESSAGECA_GLOBAL_SUPPRESS_MESSAGE 来添加属性。

如果将项目迁移到最新版本的 Visual Studio,可能会看到大量代码分析警告。 如果尚未准备好修复警告,可以通过选择分析>构建和抑制活动问题来抑制所有这些警告。

注释

不要对发布版本使用源内抑制,以防止意外传送源内抑制元数据。

SuppressMessageAttribute 属性格式

SuppressMessageAttribute 属性具有以下格式:

[Scope:SuppressMessage("Rule Category", "Rule Id", Justification = "Justification", MessageId = "MessageId", Scope = "Scope", Target = "Target")]

该属性的特性包括:

  • Category:规则的类别。 有关代码分析规则类别的详细信息,请参阅 代码质量规则

  • CheckId: 规则的标识符。 支持包括规则标识符的短名称和长名称。 短名称为 CAXXXX;长名称为 CAXXXX:FriendlyTypeName

  • Justification:用于记录消息抑制原因的文本。

  • MessageId:每个消息问题的唯一标识符。

  • Scope:禁止显示警告的目标。 如果未指定目标,系统会将其设置为属性的目标。 支持的 范围 包括:

    • module:此范围禁止对程序集发出警告。 这是一个适用于整个项目的全局范围限制。

    • resource:(仅限旧版 FxCop )此范围禁止在写入到模块(程序集)的资源文件中的诊断信息中显示警告。 对于仅分析源文件的 Roslyn 分析器诊断,在 C#/VB 编译器中不会读取或遵循此范围。

    • type:此范围禁止针对类型发出警告。

    • member:此范围禁止针对成员发出警告。

    • namespace:此范围禁止针对命名空间本身发出警告。 它不会禁止针对命名空间中的类型发出警告。

    • namespaceanddescendants:(需要编译器版本 3.x 或更高版本和 Visual Studio 2019 或更高版本)此范围禁止命名空间及其所有后代符号中的警告。 旧版分析忽略namespaceanddescendants值。

  • Target:一个标识符,指定禁止显示警告的目标。 它必须包含完全限定的组件名称。

在 Visual Studio 中看到警告时,可以通过向全局抑制文件添加抑制来查看SuppressMessageAttribute的示例。 抑制属性及其所需属性显示在预览窗口中。

SuppressMessageAttribute 用法

代码分析警告在应用 SuppressMessageAttribute 属性的级别上被抑制。 例如,可以在程序集、模块、类型、成员或参数级别应用特性。 应用此属性的目的是将抑制信息紧密耦合到发生冲突的代码。

一般抑制形式包括规则类别和规则标识符,其中包含规则名称的可选可读表示形式。 例如:

[SuppressMessage("Microsoft.Design", "CA1039:ListsAreStrongTyped")]

如果源内抑制元数据最小化存在严格的性能原因,则可以省略规则名称。 规则类别及其规则 ID 共同构成了一个足够唯一的规则标识符。 例如:

[SuppressMessage("Microsoft.Design", "CA1039")]

出于可维护性原因,不建议省略规则名称。

抑制方法体内的选择性违规

抑制属性可以应用于方法,但不能嵌入到方法主体中。 如果将 SuppressMessageAttribute 属性添加到方法上,则会抑制特定规则的所有违规。

在某些情况下,你可能想要抑制违规行为的特定实例。 请考虑将来的代码不会自动免除代码分析规则的示例。 某些代码分析规则允许你通过使用MessageIdSuppressMessageAttribute属性来抑制特定实例的违规。 旧规则通常尊重MessageId 属性,当处理特定符号(局部变量或参数)的违规时。 CA1500:VariableNamesShouldNotMatchFieldNames 是此类规则的示例。 但是,针对可执行代码(非符号)冲突的旧规则不遵循该 MessageId 属性。 此外,.NET 编译器平台(“Roslyn”)分析器不尊重该 MessageId 属性。

若要抑制规则中的特定符号违反,请为MessageId属性的SuppressMessageAttribute指定符号名称。 以下示例展示了违反CA1500:VariableNamesShouldNotMatchFieldNames的代码,其中 name 变量存在一个违规,age 变量存在另一个违规。 仅禁止与 age 符号相关的违规行为。

public class Animal
{
    int age;
    string name;

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "age")]
    private void PrintInfo()
    {
        int age = 5;
        string name = "Charlie";

        Console.WriteLine($"Age {age}, Name {name}");
    }
}

全局级抑制

托管代码分析工具检查在程序集、模块、类型、成员或参数级别应用的SuppressMessageAttribute属性。 它还会针对资源和命名空间提交违规。 这些违规必须在全球层面上实施,并且范围和目标都要明确。 例如,以下消息可以抑制命名空间冲突警告:

[module: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "MyNamespace")]

对于全局级抑制:

  • 抑制具有 namespace 作用域的警告时,它将抑制对命名空间本身的警告。 它不会禁止针对命名空间中的类型发出警告。

  • Target 始终包含完全限定的项名称。

  • 可以通过指定显式作用域来表示任何抑制。 这些抑制必须位于全局级别。 无法通过修改类型来指定成员级抑制。

  • 全局级抑制是禁止引用编译器生成的代码的消息的唯一方法,这些代码不映射到显式提供的用户源。 例如,以下代码消除对由编译器生成的构造函数的违规:

    [module: SuppressMessage("Microsoft.Design", "CA1055:AbstractTypesDoNotHavePublicConstructors", Scope="member", Target="Microsoft.Tools.FxCop.Type..ctor()")]

全局禁用文件

全局抑制文件维护全局级抑制和未指定目标的抑制。 例如,程序集级冲突的抑制存储在此文件中。 此外,此文件中存储了一些 ASP.NET 抑制,因为项目级设置不适用于表单后面的代码。 Visual Studio 在您首次在“错误列表”窗口中选择“抑制”命令的“在项目抑制文件”选项时,会创建并将一个全局抑制文件添加到您的项目中。

模块抑制范围

可以通过使用 module 范围抑制整个程序集的代码质量冲突。

例如, GlobalSuppressions 项目文件中的以下属性禁止 ASP.NET 核心项目的 ConfigureAwait 冲突:

[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2007:Consider calling ConfigureAwait on the awaited task", Justification = "ASP.NET Core doesn't use thread context to store request context.", Scope = "module")]

生成的代码

托管代码编译器和一些外部工具生成代码以帮助快速开发代码。 源文件中显示的编译器生成的代码使用 GeneratedCodeAttribute 属性进行标记。

对于源代码分析,可以在 .editorconfig 文件中取消生成的代码中的消息。 有关详细信息,请参阅 排除生成的代码

对于旧代码分析,可以选择是否取消生成的代码的代码分析警告和错误。 有关如何取消此类警告和错误的信息,请参阅 禁止显示生成的代码的代码分析警告

注释

当代码分析应用于整个程序集或单个参数时,将 GeneratedCodeAttribute 忽略它。