1. ホーム
  2. c#

[解決済み] C#のNullパラメータチェック

2023-04-06 20:39:53

質問

C# において、null が有効な値でないすべての関数にパラメータ null チェックを追加する正当な理由 (より良いエラーメッセージ以外) はありますか? 明らかに、s を使用するコードはとにかく例外を投げるでしょう。そして、そのようなチェックはコードをより遅くし、維持するのが難しくなります。

void f(SomeType s)
{
  if (s == null)
  {
    throw new ArgumentNullException("s cannot be null.");
  }

  // Use s
}

どのように解決するのですか?

そうです、正当な理由があるのです。

  • からはわからないかもしれませんが、何がヌルであるかを正確に特定します。 NullReferenceException
  • 他の条件が値を参照しないことを意味する場合でも、無効な入力でコードが失敗するようにします。
  • 例外が発生するようにします。 前に の前に発生した場合、そのメソッドは最初の参照解除の前に到達する可能性のある他の副作用を持つ可能性があります。
  • つまり、パラメータを他の何かに渡す場合、そのパラメータが その 契約
  • メソッドの要件を文書化したもので、( コード・コントラクト を使うのがよりよいでしょう)

さて、異議申し立てについてですが

  • より遅い : ということがわかりましたか? 実際に がボトルネックになっていることを発見しましたか? Nullity チェックが非常に速く、大半のケースで ではなく ボトルネックになることはありません。
  • コードのメンテナンスが難しくなる : 私は逆だと思います。私が思うに、それは より簡単 を使うほうが簡単だと思います。

そして、あなたの主張に対して。

明らかに、sを使用するコードはとにかく例外を投げます。

本当に?考えてみてください。

void f(SomeType s)
{
  // Use 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");

あまり気にしないのであれば、パラメータ名を取らないオーバーロードも可能です。

.NET 6 の更新

には 新方式 を簡略化する.NET APIの null のチェックシンタックスを簡素化します。

 ArgumentNullException.ThrowIfNull(someParameter);