5

すべてのメソッドが同じパラメーターを必要とするという点で、私はしばしば呼び出し階層を持っています。それらをインスタンスレベル(クラスのメンバー)に配置したくない場合は、各メソッドでそれらの有効性をチェックすることが意味があるかどうかを常に尋ねます。

例えば:

public void MethodA(object o){
   if(null == o){
      throw new ArgumentNullException("o");
   }
   // Do some thing unrelated to o

   MethodB(o);

   // Do some thing unrelated to o

}

public void MethodB(object o){
   if(null == o){
      throw new ArgumentNullException("o");
   }
   // Do something with o
}

Aがパラメータを使用している場合Method、それは明らかです。そこで、MethdoBでも有効性を確認する必要があります。ただし、MethodAがにo与える以外に何もしない限りMethodB、で有効性を確認することをお勧めしMethodAます。

チェックインの利点はMethodA、呼び出し先が呼び出したメソッドで例外がスローされることです。これは素晴らしいことですが、必要ですか?コールスタックはこれも示します。多分それは公的、内部的、保護されているが私的な方法では意味がないのだろうか?

例としてヌルチェックを取り上げましたが、インデックス検証や範囲検証も自己の質問に該当しますが、冗長なコードの危険性があるため、制限があると思います。どう思いますか?

アップデート

AakashMの回答を通して、私は少し正確であることがわかりました。MethodAを呼び出すだけでなくMethodB、他のことも行いますが、とは関係ありませんo。これを明確にするために例を追加しました。AakashMに感謝します。

4

3 に答える 3

9

SteveMcConnellのCodeCompleteは、「バリケード」の概念について説明しています。これは、データが信頼されていない外部と信頼されている内部の防御の壁です。バリケードに入ろうとするデータは検証プロセスを経る必要がありますが、バリケード内では、データは検証コードに縛られることなく自由に動き回ることができます。

プロジェクトにこの量の構造化と階層化を課し、それに固執することができれば、バリケード内のコードのセレモニーが少なくなり、本質が増します。しかし、すべてがうまくいかないためにバリケードを呼び出すのに必要な方法は1つだけです。

あなたの例では、MethodBですpublicMethodAこれは、唯一の呼び出し元となる将来の自動保証がないことを意味します。したがって、検証コードはそのままにしておく必要があります。しかし、それがprivateクラスの場合は、それを削除するための議論をすることができます。

についてMethodAは、実際に呼び出すだけの場合は存在しないMethodBはずです。それが将来の拡張のためのスタブであり、ある時点でそれが何かをする予定であるo場合、その検証コードも残しておく必要があります。

于 2010-07-14T10:37:10.093 に答える
1

入力値が生成される場所(呼び出し元の責任)で一度確認する必要があると思います。これは、クラスが内部クライアントによってのみ使用される場合に機能します。パブリックAPIの一部である場合、チェックを除外することはできませんが、他の回答で提案されているように、チェックを因数分解することをお勧めします。

テストの目的で、両方の方法で使用することもできます。パフォーマンスが問題Debug.Assert(o != null)になる場合は、チェックがリリースコードから削除されます。

于 2010-07-14T10:36:21.260 に答える
1

パラメータ検証を「冗長コード」とは考えていません。すべての外部エントリポイントを保護する必要があります。privateフローが到達するまでにすべてのパラメーターが有効になることがわかっているメソッドがある場合は、おそらくケースがありますが、 public(さらにはprotected)メソッドの場合は実際にはそうではありません。

于 2010-07-14T11:24:13.020 に答える