私は次のように表すことができるコードを持っています:
public class ItemService {
public void DeleteItems(IEnumerable<Item> items)
{
// Save us from possible NullReferenceException below.
if(items == null)
return;
foreach(var item in items)
{
// For the purpose of this example, lets say I have to iterate over them.
// Go to database and delete them.
}
}
}
今私はこれが正しいアプローチであるか、例外をスローするべきか疑問に思っています。例外は回避できます。戻り値は空のコレクションの反復と同じになるため、いずれにしても重要なコードは実行されませんが、一方で、コードのどこかに問題を隠している可能性があります。 DeleteItems
with null
パラメータ?これは、コードの他の場所に問題があることを示している可能性があります。
これは、サービスのメソッドで通常私が抱えている問題です。それらのほとんどは何かを実行して結果を返さないため、誰かが無効な情報を渡した場合、サービスが行うことは何もないため、返されます。
これらは2つの異なる質問です。
null
を受け入れますか?それは、コードベースのnull
に関する一般的なポリシーによって異なります。私の意見では、明示的に文書化されている場所を除いてすべての場所でnull
を禁止することは非常に良い習慣ですが、コードベースがすでに持っている規則に固執することはさらに良い習慣です。
空のコレクションを受け入れますか?私の意見では:はい、絶対に。ゼロという概念に不満を抱いている開発者の一部が驚いたとしても、数学的に正しいことを行うよりも、すべての呼び出し元を空でないコレクションに制限する方がはるかに努力します。
@KilianFothがすでに言ったように、あなたの一般的な方針に固執してください。 null
を空のリストの「省略形」として扱う場合は、そのようにします。
null
値に関する一貫したポリシーがない場合は、次の方法をお勧めします。
null
は、「通常の」タイプでは表現できない状況を表すために予約する必要があります。 null
を使用して「わからない」を表します。そして、これは良い選択です。この値を不注意に使用しようとすると、例外が発生します。これは正しいことです。
空のリストの省略形としてnull
を使用しても、要素がゼロのリストである完全な表現がすでに存在するため、そのように修飾することはできません。また、リストを処理するコードのすべての部分で、有効な短縮形null
をチェックする必要があるため、技術的に悪い選択です。
DeleteItems()
メソッドの場合、空のリストを渡すと、事実上何もしません。例外としてスローするのではなく、すぐに戻るだけの引数として許可します。
もちろん、呼び出し元は最初にゼロ要素をチェックし、その場合はDeleteItems()
呼び出しをスキップできます。 Web APIについて話している場合、効率上の理由から、呼び出し元すべきは実際にそれを行って、不要なトラフィックと往復の待ち時間を回避します。しかし、私はあなたのAPIがそれを強制するべきではないと思います。
例外をスローし、呼び出しコードでnullを処理します。
設計規則として、パラメーター値としてnullを使用しないようにしてください。 nullは実際には例外になるため、一般にNullPointerExceptionが削減されます。
それ以外に、残りのコードを見てください。これがプロジェクトで一般的なパターンである場合は、一貫性を維持してください。
一般的に言えば、例外のスローは、例外的な状況、つまり、コードに現在のコンテキストで実行する適切なアクションがない場合のために予約する必要があります。
この思考プロセスをこの状況に適用できます。これがパブリックメソッドを持つパブリッククラスであるとすると、パブリックAPIがあり、理論的には渡されるものを制御できません。
あなたのコードはそれを何と呼んでいるのか(それがそうではないので)コンテキストを持っていません、そしてあなたがnull値で合理的にできることは何もありません。これは確かにArgumentNullException
の候補になります。
この質問は例外についてではなく、null
が有効な引数であることについてのようです。
したがって、何よりもまず、null
がそのメソッドの引数に許可される値であるかどうかを決定する必要があります。そうであれば、例外は必要ありません。そうでない場合は、例外が必要です。
null
を許可するかどうかは、議論の余地があります。それについての多くのGoogleヒットが示しています。つまり、明確な答えは得られず、作業している場所での意見や伝統次第です。
競合の別の領域は、ライブラリ関数がそのようなことについてreallyに厳密であるか、または誤ったパラメーターを「修正」しようとしない限り、可能な限り寛容であるかどうかです。これを、ネットワークプロトコル、メール転送などの世界(プログラミングのメソッドと同じようにインターフェイスコントラクトです)と比較してください。そこでは、通常、ポリシーは送信側がプロトコルにできる限り厳密に準拠し、受信側が邪魔にならないように作業を進めて、処理できるようにすることです。
それであなたは決めなければなりません:null
処理のようなかなり大規模なポリシーを強制することは本当にライブラリメソッドの仕事ですか?特に、ライブラリが他の人々(異なるポリシーを持つ可能性がある)も使用している場合。
私はおそらくnull
値を許可し、それらのセマンティクスを定義して文書化することを誤るでしょう(つまり、null = empty array
(この場合)、例外をスローしないnless他の同様のコード(「ライブラリ」スタイルのコード)の99%が、それとは逆の方法で実行します。