パブリックメソッドの引数を検証することをお勧めします。
- 彼がnullを期待していない場合、nullをチェックする必要がありますか?
- メソッドはパラメータを検証する必要がありますか?
- MSDN-CA1062:パブリックメソッドの引数を検証します(.NETの背景がありますが、質問はC#固有ではありません)
動機は理解できます。モジュールが誤った方法で使用される場合は、予測できない動作ではなく、すぐに例外をスローする必要があります。
気になるのは、モジュールの使用中に発生する可能性のあるエラーは間違った引数だけではないということです。推奨事項に従ってエラーのエスカレーションを望まない場合に、チェックロジックを追加する必要があるいくつかのエラーシナリオを以下に示します。
- 着信-予期しない引数
- 着信-モジュールの状態が間違っています
- 外部呼び出し-予期しない結果が返されました
- 外部呼び出し-予期しない副作用(呼び出しモジュールへの二重入力、他の依存関係の状態を壊す)
私はこれらすべての条件を考慮して、1つのメソッド(申し訳ありませんが、C#ではありません)で単純なモジュールを作成しようとしました:
public sealed class Room
{
private readonly IDoorFactory _doorFactory;
private bool _entered;
private IDoor _door;
public Room(IDoorFactory doorFactory)
{
if (doorFactory == null)
throw new ArgumentNullException("doorFactory");
_doorFactory = doorFactory;
}
public void Open()
{
if (_door != null)
throw new InvalidOperationException("Room is already opened");
if (_entered)
throw new InvalidOperationException("Double entry is not allowed");
_entered = true;
_door = _doorFactory.Create();
if (_door == null)
throw new IncompatibleDependencyException("doorFactory");
_door.Open();
_entered = false;
}
}
今では安全です=)
かなり気味悪いです。しかし、何十ものメソッド、複雑な状態、そして多くの外部呼び出し(依存関係注入の愛好家!)動作をオーバーライドできるモジュール(C#の非シールクラス)を呼び出す場合は、外部呼び出しを行っているため、呼び出し元のスコープでは結果を予測できません。
要約すると、正しい方法は何ですか?なぜですか?以下のオプションから選択できる場合は、追加の質問に答えてください。
モジュール全体の使用状況を確認してください。単体テストが必要ですか?そのようなコードの例はありますか?依存関係の注入は、使用が制限されている必要がありますか?これらのチェックをデバッグ時(リリースには含めない)に移動するのは現実的ではありませんか?
引数のみをチェックします。私の経験では、引数チェック、特にnullチェックは、引数エラーが複雑なミスやエラーのエスカレーションにつながることはめったにないため、最も効果的なチェックではありません。ほとんどの場合NullReferenceException
、次の行でを取得します。では、なぜ引数チェックはそれほど特別なのでしょうか。
モジュールの使用状況をチェックしません。それは非常に不人気な意見ですが、その理由を説明できますか?