CA2208:正确实例化参数异常

属性
规则 ID CA2208
标题 正确实例化参数异常
类别 使用情况
修复是中断修复还是非中断修复 非中断
在 .NET 8 中默认启用 作为建议

原因

如果方法具有参数,并且引发了异常类型 ArgumentException 或其派生类型,则它应正确调用接受 paramName 参数的构造函数。 可能的原因包括以下情况:

  • 对异常类型的默认(无参数)构造函数进行调用,该构造函数也具有接受paramName参数的构造函数(或派生自ArgumentException该构造函数)。
  • 向异常类型 ArgumentException 或其派生类型的参数化构造函数传递了错误的字符串参数。
  • ArgumentException 异常类型或其派生类型的构造函数的 message 参数传递了其中一个参数名称。

规则说明

请勿调用默认构造函数,而是调用允许提供更有意义的异常消息的构造函数重载之一。 异常消息应面向开发人员,并清楚地说明错误情况以及如何纠正或避免异常。

ArgumentException 及其派生类型的一个和两个字符串构造函数的签名与 messageparamName 参数位置不一致。 确保使用正确的字符串参数调用这些构造函数。 签名如下:

如何解决冲突

若要解决此规则的冲突,请调用使用消息和/或参数名称的构造函数,并确保参数对于要调用的 ArgumentException 类型是正确的。

提示

Visual Studio 中提供了针对参数名称位置错误的代码修补程序。 若要使用它,请将光标置于警告行上,然后按“Ctrl+.”(句点)。 从显示的选项列表中选择“交换参数顺序”。

CA2208 的代码修补程序 - 交换参数。

如果将参数名而不是消息传递给 ArgumentException(String) 方法,修补程序将改为提供切换到双参数构造函数的选项。

CA2208 的代码修补程序 - 切换到双参数构造函数。

何时禁止显示警告

仅当使用正确的字符串参数调用参数化构造函数时,才可禁止显示此规则的警告。

抑制警告

如果只想抑制单个冲突,请将预处理器指令添加到源文件以禁用该规则,然后重新启用该规则。

#pragma warning disable CA2208
// The code that's violating the rule is on this line.
#pragma warning restore CA2208

若要对文件、文件夹或项目禁用该规则,请在配置文件中将其严重性设置为 none

[*.{cs,vb}]
dotnet_diagnostic.CA2208.severity = none

有关详细信息,请参阅如何禁止显示代码分析警告

配置代码以进行分析

使用下面的选项来配置代码库的哪些部分要运行此规则。

可以仅为此规则、为适用的所有规则或为适用的此类别(设计)中的所有规则配置此选项。 有关详细信息,请参阅代码质量规则配置选项

包含特定的 API 图面

你可以根据代码库的可访问性,配置要针对其运行此规则的部分。 例如,若要指定规则应仅针对非公共 API 图面运行,请将以下键值对添加到项目中的 .editorconfig 文件:

dotnet_code_quality.CAXXXX.api_surface = private, internal

默认情况下,CA2208 规则适用于所有 API 图面(公共、内部和私有)。

示例

下面的代码演示了一个错误地实例化 ArgumentNullException 实例的构造函数。

public class Book
{
    public Book(string title)
    {
        Title = title ??
            throw new ArgumentNullException("All books must have a title.", nameof(title));
    }

    public string Title { get; }
}
Public Class Book

    Private ReadOnly _Title As String

    Public Sub New(ByVal title As String)
        ' Violates this rule (constructor arguments are switched)            
        If (title Is Nothing) Then
            Throw New ArgumentNullException("title cannot be a null reference (Nothing in Visual Basic)", "title")
        End If
        _Title = title
    End Sub

    Public ReadOnly Property Title()
        Get
            Return _Title
        End Get
    End Property

End Class

下面的代码通过切换构造函数参数来解决前面的冲突。

public class Book
{
    public Book(string title)
    {
        Title = title ??
            throw new ArgumentNullException(nameof(title), "All books must have a title.");
    }

    public string Title { get; }
}
Public Class Book

    Private ReadOnly _Title As String

    Public Sub New(ByVal title As String)
        If (title Is Nothing) Then
            Throw New ArgumentNullException("title", "title cannot be a null reference (Nothing in Visual Basic)")
        End If

        _Title = title
    End Sub

    Public ReadOnly Property Title()
        Get
            Return _Title
        End Get
    End Property

End Class