はい、正当な理由があります:
- nullを正確に識別しますが、これは
NullReferenceException
- 他の条件が値の参照解除を意味しない場合でも、無効な入力でコードが失敗するようにします
- これにより、最初の間接参照の前に到達する可能性のある他の副作用がメソッドに発生する前に、例外が発生します。
- これは、パラメータを他の何かに渡した場合、それらの契約に違反していないことを確信できることを意味します
- メソッドの要件を文書化します(もちろん、コードコントラクトを使用する方がさらに優れています)
今あなたの異議について:
- 遅い:これが実際にコードのボトルネックであることがわかりましたか、それとも推測していますか?ヌルチェックは非常に迅速であり、ほとんどの場合、ボトルネックになることはありません。
- それはコードを維持するのを難しくします:私は反対だと思います。パラメータをnullにできるかどうかが明確になり、その条件が適用されると確信できるコードを使用する方が簡単だと思います。
そしてあなたの主張のために:
明らかに、sを使用するコードはとにかく例外をスローします。
本当に?考えてみましょう:
void f(SomeType s)
{
Console.WriteLine("I've got a message of {0}", s);
}
を使用しますs
が、例外はスローされません。以下のために、それは無効だ場合はs
nullにすること、そしてそれはその何かの間違ったことを示し、例外はここで最も適切な行動です。
ここで、これらの引数検証チェックをどこに置くかは別の問題です。自分のクラス内のすべてのコードを信頼することを決定できるので、プライベートメソッドを気にしないでください。アセンブリの残りの部分を信頼することを決定できるので、内部メソッドを気にしないでください。パブリックメソッドの引数をほぼ確実に検証する必要があります。
補足:の単一パラメーターコンストラクターのオーバーロードはArgumentNullException
パラメーター名である必要があるため、テストは次のようになります。
if (s == null)
{
throw new ArgumentNullException("s");
}
または、拡張メソッドを作成して、やや簡潔にすることもできます。
s.ThrowIfNull("s");
私のバージョンの(汎用)拡張メソッドでは、null以外の場合は元の値を返すようにして、次のように記述できるようにします。
this.name = name.ThrowIfNull("name");
あまり気にしないのであれば、パラメータ名をとらないオーバーロードを設定することもできます。