次の方法で共有


CA2208:引数の例外を正しくインスタンス化します

プロパティ
ルール ID CA2208
Title 引数の例外を正しくインスタンス化します
[カテゴリ] 使用方法
修正が中断ありか中断なしか なし
.NET 10 で既定で有効 提案として

原因

メソッドにパラメーターがあり、それが ArgumentException である (または派生した) 例外の型をスローする場合、paramName パラメーターを正しく受け入れるコンストラクターを呼び出すことが期待されています。 次のような状況によって、引き起こされる可能性があります。

  • 呼び出しは、ArgumentException パラメーターを受け取るコンストラクターを持つ例外型の既定の (パラメーターなしの) コンストラクターparamNameに対して行われます。
  • 不適切な文字列の引数が、ArgumentException である (またはそれから派生した) 例外の型のパラメーター化されたコンストラクターに渡される。 たとえば、 paramName 引数は、メソッドのいずれかのパラメーターの名前と一致しません。
  • パラメーター名は、messageである、または派生した例外型のコンストラクターのArgumentException引数に渡されます。

規則の説明

既定のコンストラクターを呼び出す代わりに、より詳しい例外メッセージを提供するコンストラクターのオーバーロードを呼び出すようにします。 例外メッセージは、開発者を対象とし、エラー状態と、例外を修正または回避する方法を明確に説明するものである必要があります。

ArgumentException およびその派生型の文字列コンストラクターが 1 つのシグネチャと、2 つのシグネチャでは、message および paramName パラメーターの位置に一貫性がありません。 正しい文字列引数を指定して、これらのコンストラクターを呼び出すようにしてください。 シグネチャは次のとおりです。

違反の修正方法

この規則違反を修正するには、メッセージまたはパラメーター名、あるいはその両方を受け取るコンストラクターを呼び出し、呼び出される ArgumentException の型に対して引数が適切であることを確認します。

ヒント

不適切に配置されたパラメーター名に関するコード修正は、Visual Studio で使用できます。 これを使用するには、警告行にカーソルを置き、Ctrl+. (ピリオド) を押します。 表示されるオプションの一覧から [引数の順序を入れ替える] を選択します。

CA2208 (引数の入れ替え) のコード修正。

メッセージではなくパラメーター名が ArgumentException(String) メソッドに渡された場合、修正ツールには 2 つの引数を持つコンストラクターに切り替えるオプションが用意されています。

CA2208 (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

メモ

XXXXCAXXXX 部分を該当するルールの 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

次のコードは、メソッドのパラメーターに一致しないArgumentNullExceptionparamNameを誤ってスローするメソッドを示しています。 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