2
public void PublicMethod(FooBar fooBar)
{
    if (fooBar == null)
        throw new ArgumentNullException("fooBar", "fooBar cannot be null");

    // log the call [added:  Thanks S.Lott]
    _logger.Log("PublicMethod called with fooBar class " + fooBar.Classification);

    int action = DetermineAction();
    PrivateMethod(fooBar, action);
}

private void PrivateMethod(FooBar fooBar, int action)
{
    if (fooBar == null)
        throw new ArgumentNullException("fooBar", "fooBar cannot be null");  // Is this line superfluous?

    /*
        Do something
    */
}

パブリック インターフェイスで入力が既にチェックされている場合、プライベート メソッドでこの種のエラー チェックをスキップしても問題ありませんか? 通常、ある程度の経験則があります...

編集:

おそらく、ArgumentNullException はあまり良い例ではありません。なぜなら、両方のレベルでチェックする必要があるが、異なるエラー メッセージを返すという引数を作成できるからです。

4

9 に答える 9

3

私はノーと言うでしょう。

この場合、null 可能性が既にチェックされていることを知っていることは確かですが、2 か月後に最年少のインターンがやって来て、PrivateMethod も呼び出す PublicMethod2 を作成しますが、見よ、彼は null をチェックするのを忘れていました。

于 2008-10-08T14:50:21.600 に答える
2

public メソッドは実際には foobar を使用しないため、なぜチェックしているのかわかりません。現在のプライベート メソッドは気にしますが、気にするのはプライベート メソッドの責任です。実際、プライベート メソッドの要点は、すべての責任を委任することです。

メソッドは、実際に使用する入力をチェックします。通過するだけのものはチェックしません。

別のサブクラスに同じ public メソッドがあるが、いくつかの別の private メソッドの実装 (null を許容できるもの) がある場合、次はどうなるでしょうか? 新しいサブクラスに対して不適切な制約を持つパブリック メソッドがあります。

さまざまなプライベート実装が自由に正しいことを行うことができるように、パブリック メソッドで行うことはできるだけ少なくしたいと考えています。「過剰チェック」または「念のため」のチェックは行わないでください。責任を委任します。

于 2008-10-08T15:00:30.240 に答える
1

契約による設計 ( http://en.wikipedia.org/wiki/Design_by_contract ) を使用する場合、通常、正しい呼び出しを行う、つまり有効なパラメーターを渡すのはクライアント (パブリック メソッド) の責任です。この特定のシナリオでは、null が有効な入力値のセットに属しているかどうかに依存するため、3 つのオプションがあります。

1) Null は有効な値です。例外またはエラーをスローすると、コントラクトが破られることになります。サーバー (プライベート メソッド) は null を処理する必要があり、文句を言うべきではありません。

2) Null は無効な値であり、コントロール内のコードによって渡されます。どのように反応するかを決定するのはサーバー (プライベート メソッド) 次第です。明らかに、例外をスローする方が状況を処理するより適切な方法ですが、その例外をスタックのどこか別の場所で処理しなければならないというコストがかかります。例外は、プログラミングの失敗によって引き起こされた契約違反に対処する最善の方法ではありません。契約にすでに違反している場合ではなく、ソフトウェアで制御できない環境問題のために契約を履行できない場合に、例外をスローする必要があります。失敗は、プライベート メソッドの先頭にアサーションを貼り付けてパラメーターが null でないことを確認することにより、より適切に処理されます。これにより、コードの複雑さが抑えられます。

3) 次に、防御的プログラミングがあります ( http://en.wikipedia.org/wiki/Defensive_programming )。コントロール外の外部コードによって渡されたパラメーターを処理する場合、コードの直接レイヤーは、パラノイア レベルのチェックを実行し、外部世界との通信契約に従ってエラーを返す必要があります。次に、外部に公開されていないコード層をさらに深く掘り下げると、契約によるプログラミングに固執する方が理にかなっています。

于 2008-10-08T16:10:45.933 に答える
1

考えもしなかったことがいつ起こるかはわかりません。(そして、申し訳ありませんが安全です)

于 2008-10-08T15:09:42.637 に答える
0

それは、null 値がメソッドのエラーを示しているかどうかによって異なります。メソッドは、オブジェクトへのメッセージを呼び出すこともできることに注意してください。それらはオブジェクトの状態にも作用します。パラメータは、送信されるメッセージの種類を特殊化できます。

  • publicMethod() がパラメータを使用せず、privateMethod() がパラメータを使用している間にインスタンスの状態を変更する場合、publicMethod ではエラーと見なさず、privateMethod() でエラーと見なしてください。
  • publicMethod() が状態を変更しない場合は、エラーと見なします。

後者のケースは、オブジェクトの内部機能へのインターフェイスを提供するものと見なすことができます。

于 2008-10-08T16:05:05.147 に答える
0

PrivateMethod が既に検証済みの入力で頻繁に呼び出され、ユーザー入力ではめったに呼び出されない場合、PrivateMethod でエラー チェックを行わずに (PublicMethod でパラメーターとPrivateMethod を呼び出す)

また、PublicMethod_impl (「実装」用) のようなプライベート メソッドを呼び出すので、それが内部使用/非チェック メソッドであることは明らかです。

私は、この設計がより堅牢なアプリケーションにつながると主張しています。なぜなら、何がいつチェックされるかを考える必要があるからです。パラメータを常にチェックしている人は、「何かをチェックしたので、すべてをチェックした」という罠に陥ることが多々あります。

この例として、以前の同僚 (C でプログラミング) は、ポインターを使用する前に、ポインターが null かどうかを常にチェックしていました。通常、彼のコード内のポインターは起動時に初期化され、変更されることはありませんでした。そのため、null になる可能性は非常に低かったのです。さらに、ポインターには 1 つの正しい値と 65535 の可能性のある間違った値があり、彼はそれらの間違った値の 1 つだけをチェックしていました。

于 2008-10-08T17:15:06.597 に答える
0

少なくとも、PrivateMethod には null 以外の FooBar が必要であり、PublicMethod がこれをチェックするというコメントを入れてください。

于 2008-10-08T14:49:56.407 に答える
0

答えは「はい、チェックをやり直してください」だと思います。理由は次のとおりです。

  • プライベート メンバーは、将来、コードの別のパスから再利用される可能性があるため、そのような状況に対して防御的にプログラムします。
  • プライベート メソッドで単体テストを実行する場合

これを検出でき、プライベート メソッドでの null 参照の潜在的な使用にフラグを立てない静的アナライザーがあれば、私の見解は変わるかもしれません。

于 2008-10-08T16:32:09.757 に答える
0

「プライベート」メソッドをプライベートまたは保護としてマークすることもできます。

于 2008-10-08T14:54:38.177 に答える