| プロパティ | 値 |
|---|---|
| ルール ID | CA2208 |
| Title | 引数の例外を正しくインスタンス化します |
| [カテゴリ] | 使用方法 |
| 修正が中断ありか中断なしか | なし |
| .NET 10 で既定で有効 | 提案として |
原因
メソッドにパラメーターがあり、それが ArgumentException である (または派生した) 例外の型をスローする場合、paramName パラメーターを正しく受け入れるコンストラクターを呼び出すことが期待されています。 次のような状況によって、引き起こされる可能性があります。
- 呼び出しは、ArgumentException パラメーターを受け取るコンストラクターを持つ例外型の既定の (パラメーターなしの) コンストラクター
paramNameに対して行われます。 - 不適切な文字列の引数が、ArgumentException である (またはそれから派生した) 例外の型のパラメーター化されたコンストラクターに渡される。 たとえば、
paramName引数は、メソッドのいずれかのパラメーターの名前と一致しません。 - パラメーター名は、
messageである、または派生した例外型のコンストラクターのArgumentException引数に渡されます。
規則の説明
既定のコンストラクターを呼び出す代わりに、より詳しい例外メッセージを提供するコンストラクターのオーバーロードを呼び出すようにします。 例外メッセージは、開発者を対象とし、エラー状態と、例外を修正または回避する方法を明確に説明するものである必要があります。
ArgumentException およびその派生型の文字列コンストラクターが 1 つのシグネチャと、2 つのシグネチャでは、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) メソッドに渡された場合、修正ツールには 2 つの引数を持つコンストラクターに切り替えるオプションが用意されています。
どのようなときに警告を抑制するか
パラメーター化されたコンストラクターが正しい文字列引数で呼び出される場合にのみ、この規則による警告を抑制しても問題ありません。
警告を抑制する
単一の違反を抑制するだけの場合は、ソース ファイルにプリプロセッサ ディレクティブを追加して無効にしてから、規則をもう一度有効にします。
#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_surface オプションを設定することで、アクセスの可否に基づいてこのルールを実行するコードベースの部分を構成できます。 たとえば、非パブリック API サーフェイスでのみ規則を実行するように指定するには、プロジェクトの .editorconfig ファイルに次のキーと値のペアを追加します。
dotnet_code_quality.CAXXXX.api_surface = private, internal
メモ
XXXX の CAXXXX 部分を該当するルールの ID に置き換えます。
既定では、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
次のコードは、メソッドのパラメーターに一致しないArgumentNullExceptionでparamNameを誤ってスローするメソッドを示しています。
descriptionはメソッド パラメーターではなくローカル変数であるため、ルールが発動します。
public class Product
{
public string? Description { get; set; }
public string Name { get; set; } = string.Empty;
}
public class Example
{
// Violates CA2208: 'description' is not a parameter of this method.
public void ProcessProduct(Product product)
{
string? description = product.Description;
if (description is null)
{
throw new ArgumentNullException(nameof(description), $"Product named {product.Name} had no description!");
}
// Process description...
}
}
Public Class Product
Public Property Description As String
Public Property Name As String = String.Empty
End Class
Public Class Example
' Violates CA2208: 'description' is not a parameter of this method.
Public Sub ProcessProduct(ByVal product As Product)
Dim description As String = product.Description
If description Is Nothing Then
Throw New ArgumentNullException(NameOf(description), $"Product named {product.Name} had no description!")
End If
' Process description...
End Sub
End Class
次のコードでは、代わりに InvalidOperationException を使用して以前の違反を修正します。これは、オブジェクトの状態が無効な場合に適しています。
public class Product
{
public string? Description { get; set; }
public string Name { get; set; } = string.Empty;
}
public class Example
{
// Fixed: Use InvalidOperationException for invalid object state.
public void ProcessProduct(Product product)
{
string? description = product.Description;
if (description is null)
{
throw new InvalidOperationException($"Product named {product.Name} had no description!");
}
// Process description...
}
}
Public Class Product
Public Property Description As String
Public Property Name As String = String.Empty
End Class
Public Class Example
' Fixed: Use InvalidOperationException for invalid object state.
Public Sub ProcessProduct(ByVal product As Product)
Dim description As String = product.Description
If description Is Nothing Then
Throw New InvalidOperationException($"Product named {product.Name} had no description!")
End If
' Process description...
End Sub
End Class
関連規則
.NET