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

CA2208 コード分析ルールは、引数の例外を構築する際の一般的な間違いをチェックします。主な引数例外クラスには、ArgumentException、ArgumentNullException、および ArgumentOutOfRangeException の 3 つがあります。残念ながら、これらを使用する際に間違いを犯しやすいです。 CA2208 がチェックする一般的な間違いとその修正方法 (および代わりに警告を抑制する場合) について説明します。

ケース 1 – paramName / メッセージが間違った順序で渡される

引数の例外パラメーターを間違った順序で渡すと、次のような CA2208 警告が表示されます:

この問題の例を次に示します。パラメータの順序は (paramName, message) ですが、誤って (message, paramName) として渡されます:

//Method signature
public ArgumentOutOfRangeException(string? paramName, string? message);

//Example of passing the parameters in the wrong order:
throw new ArgumentOutOfRangeException("Valid range: 100-999", nameof(id));
Code language: C# (cs)

注:さらに紛らわしいことに、ArgumentException のパラメーターの順序は逆です (message、paramName)。

ここでの簡単な答えは、引数を正しい順序で配置することです。ただし、代わりに名前付き引数を使用することをお勧めします。

同じタイプ (この場合は文字列) の 2 つのパラメーターが隣り合っている場合、上記のように誤ってそれらを転置するのは非常に簡単です。一般に、この種の問題を防ぐ最善の方法は、名前付き引数を使用する習慣を身に付けることです (これにより、パラメーターの順序が無関係になります)。名前付き引数を使用して引数例外を作成する例を次に示します:

throw new ArgumentOutOfRangeException(message: "Valid range: 100-999", paramName: nameof(id));
Code language: C# (cs)

パラメータ名だけを ArgumentException に渡す

ArgumentException には paramName だけを受け入れるオーバーロードがありません 、しかし、メッセージだけを受け入れるものがあります . message のパラメータ名を渡していることをコンパイラが認識できる場合 、前のセクションで示したのと同じ CA2208 警告を報告します。これを引き起こす原因の例を次に示します:

throw new ArgumentException(nameof(id));
Code language: C# (cs)

これは本当に問題ですか?それはあなた次第です。おそらく、このようにパラメーター名だけを渡し、CA2208 警告を取り除きたいと思うでしょう。その場合、次のコード行で CA2208 を抑制することができます:

#pragma warning disable CA2208 // Instantiate argument exceptions correctly
 throw new ArgumentException(nameof(id));
#pragma warning restore CA2208 // Instantiate argument exceptions correctly
Code language: C# (cs)

ケース 2 – paramName がメソッドのパラメーターと一致しない

paramName を渡すとき 引数の例外に対して、コンパイラはそれがメソッド パラメーターの 1 つの名前と一致するかどうかをチェックします。一致しない場合は、次のような CA2208 警告が表示されます:

まず、paramName が必要な場合 メソッドのパラメーター名を正確に一致させるには、名前をハードコーディングする代わりに nameof() 演算子を使用することをお勧めします:

public Person Get(string uniqueId)
{
	throw new ArgumentNullException(paramName: nameof(uniqueId));
}
Code language: C# (cs)

次に、パラメーターの名前ではなく、意図的にパラメーターのプロパティ名を使用しているとします。以下に例を示します:

public void Post(Person person)
{
	throw new ArgumentNullException(paramName: nameof(person.FirstName));
}
Code language: C# (cs)

このようにパラメーターのプロパティに対して引数の例外をスローしてもまったく問題ありません。明らかに paramName パラメータ名と一致しません。この場合、本当に CA2208 警告を取り除きたい場合は、次の行でそれを抑制することができます:

#pragma warning disable CA2208 // Instantiate argument exceptions correctly
throw new ArgumentNullException(paramName: nameof(person.FirstName));
#pragma warning restore CA2208 // Instantiate argument exceptions correctly
Code language: C# (cs)

ケース 3 – パラメーターなしのコンストラクターの使用

引数例外のパラメーターなしのコンストラクター (つまり、new ArgumentException()) を使用すると、次のような CA2208 警告が表示されます:

パラメーターなしのコンストラクターを使用することは技術的に間違っているわけではありませんが (結局のところ存在します)、ほとんどの場合、message / paramName で渡すのが理にかなっています。 例外に関する特定の情報を提供します。

ただし、パラメーターなしのコンストラクターを使用する方が理にかなっていると判断し、CA2208 警告を取り除きたい場合は、次の行で CA2208 を抑制することができます:

#pragma warning disable CA2208 // Instantiate argument exceptions correctly
throw new ArgumentNullException();
#pragma warning restore CA2208 // Instantiate argument exceptions correctly
Code language: C# (cs)