CA2208:正确实例化参数异常
属性 | 值 |
---|---|
规则 ID | CA2208 |
标题 | 正确实例化参数异常 |
类别 | 使用情况 |
修复是中断修复还是非中断修复 | 非中断 |
在 .NET 8 中默认启用 | 作为建议 |
原因
如果方法具有参数,并且引发了异常类型 ArgumentException 或其派生类型,则它应正确调用接受 paramName
参数的构造函数。 可能的原因包括以下情况:
- 对异常类型的默认(无参数)构造函数进行调用,该构造函数也具有接受
paramName
参数的构造函数(或派生自ArgumentException该构造函数)。 - 向异常类型 ArgumentException 或其派生类型的参数化构造函数传递了错误的字符串参数。
- 为 ArgumentException 异常类型或其派生类型的构造函数的
message
参数传递了其中一个参数名称。
规则说明
请勿调用默认构造函数,而是调用允许提供更有意义的异常消息的构造函数重载之一。 异常消息应面向开发人员,并清楚地说明错误情况以及如何纠正或避免异常。
ArgumentException 及其派生类型的一个和两个字符串构造函数的签名与 message
和 paramName
参数位置不一致。 确保使用正确的字符串参数调用这些构造函数。 签名如下:
ArgumentException(string message)
ArgumentException(string message, string paramName)
ArgumentNullException(string paramName)
ArgumentNullException(string paramName, string message)
ArgumentOutOfRangeException(string paramName)
ArgumentOutOfRangeException(string paramName, string message)
DuplicateWaitObjectException(string parameterName)
DuplicateWaitObjectException(string parameterName, string message)
如何解决冲突
若要解决此规则的冲突,请调用使用消息和/或参数名称的构造函数,并确保参数对于要调用的 ArgumentException 类型是正确的。
提示
Visual Studio 中提供了针对参数名称位置错误的代码修补程序。 若要使用它,请将光标置于警告行上,然后按“Ctrl+.”(句点)。 从显示的选项列表中选择“交换参数顺序”。
如果将参数名而不是消息传递给 ArgumentException(String) 方法,修补程序将改为提供切换到双参数构造函数的选项。
何时禁止显示警告
仅当使用正确的字符串参数调用参数化构造函数时,才可禁止显示此规则的警告。
抑制警告
如果只想抑制单个冲突,请将预处理器指令添加到源文件以禁用该规则,然后重新启用该规则。
#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