21

throw回避できるエラーを考えたほうがいい場合はありますか?

私は特にとについて考えていDivideByZeroExceptionますArgumentNullException

例えば:

double numerator = 10;
double denominator = getDenominator();

if( denominator == 0 ){
   throw new DivideByZeroException("You can't divide by Zero!");
}

このようなエラーをスローする理由はありますか?

注:私はこれらのエラーをキャッチすることについて話しているのではなく、特にそれらをスローする正当な理由があるかどうかを知ることについて話しているのです。

繰り返すだけ

私があなたに与えた例では、おそらくエラーを処理したほうがよいことを私は知っています。おそらく、質問は言い換えられるべきです。この場所throwで処理するのではなく、これらのエラーの1つに理由がありますか。

4

16 に答える 16

20

Int64に適合しない非常に大きな整数を処理するライブラリを作成するとし、作成した除算アルゴリズムに対してDivideByZeroExceptionをスローしたい場合があります。

于 2010-04-08T15:57:49.130 に答える
14

.NETランタイムは、これらの例外をスローするのにすでに非常に優れています。また、何が問題であるかを非常によく説明しているため、例外メッセージに適切なコメントを追加することはできません。「ゼロ除算はできません」は何の価値もありません。

ただし、クライアントコードによって渡された値をスクリーニングすることで、これらの例外の多くを回避できます。クライアントコードがnullを渡した場合は、引数の名前を持つArgumentNullExceptionが必要になります。DivideByZeroをトリップする可能性のあるものを渡した場合は、ArgumentExceptionが必要になります。

于 2010-04-08T15:56:57.913 に答える
5

これを行う理由は絶対にあります。ほとんどの例外を投げる質問と同様に、チームで作業する開発者として自分のことを考える必要があります。あなたが書いているものは、別のシステムの一部であるか、ライブラリまたはコンポーネントである可能性があります。

数学ライブラリを作成し、それらを分割するという関数Divide(int a, int b)を使用している場合、他の誰かがあなたのメソッドを使用してゼロを渡す場合は、例外をスローして、開発者として、彼らが失敗したことを認識できるようにします。 。

例外をスローしない場合は、コードにバグが発生します。除算方法を使用し、値10と0を入力すると、10/0が生成され、例外が発生します。正解はエラーのみです。エラーが発生しないように値を変更するか、0を返すことにした場合、それは私が期待していることではありません-私の除算は完全に機能し、問題に気付くことはないと思います。10/0は0ではないので、それが間違った答えであることに気付かずに、その0を取得して、他の計算で使用することもできます。

于 2010-04-08T16:04:39.063 に答える
4

例外を処理するには、例外のみを使用する必要があります。

この場合、ゼロは無効なユーザー入力であるように見えます。例外が適切になるに、無効なユーザー入力をチェックし、それに応じて処理する必要があります。

入力を適切に処理する限り、がDivideByZeroException発生する理由はありません。入力を検証した後でも受信した場合DivideByZeroExceptionは、実際に問題があることがわかります(この場合、例外が適切です)。

于 2010-04-08T15:53:38.647 に答える
3

UIと直接対話するコードについて話している場合は、いいえ。私はあなたがしたい理由を考えることができません。

ただし、他の開発者が使用するクラス/オブジェクトを構築していて、明らかに愚かなデータを渡した場合は、検証中に適切なエラーをスローします。

于 2010-04-08T15:55:38.773 に答える
2

BigIntegerライブラリを作成している場合は、絶対に適切なDivideByZero例外をスローする必要があります。ショッピングカートライブラリを作成している場合は、おそらくそうではありません。

現時点では、を投げる正当な理由を考えることはできませんNullReferenceExceptionHummingBirdFeeder.OpenSugarWaterDispenser(Dispenser dispenser, int flowRate)「最初のパラメータは、開きたい砂糖水ディスペンサーです」というドキュメントを使用してAPIを作成する場合。そして、誰かがやって来てこのメソッドにnull値を渡した場合は、間違いなく。をスローする必要がありArgumentNullExceptionます。

ただし、APIを外すNullReferenceExceptionのは怠惰です。なぜなら、それは間違っており、内部の一部がリークされるからです。

追加するために編集:

質問を参照するように変更したArgumentNullExceptionので、答えは簡単です。はい、これらの状況では必ずその種の例外をスローする必要があります。

  • あなたはパブリックメソッドを書いています。
  • 引数にnull値を取得することは、何らかの形で不適切です(つまり、その特定の引数がないとメソッドは意味をなしません)。
  • メソッドのドキュメントには、null値は許可されていないことが示されています。

その場合、メソッドが最初に行うべきことは、null値をチェックし、条件に違反した場合は例外をスローすることです。

プライベートメソッドまたは内部メソッドを作成している場合、ほとんどの場合、リリースビルドの実行時にパラメーターを検証する必要はありません。自分のコードが自分のコードを正しく呼び出すようにすることができます。その保証を作成するのに役立つ1つのことは、アサーションを追加してデバッグビルドのパラメーターを検証することです。

Debug.Assert(dispenser != null);

このようにして、コードが正しく機能していることを確認し、リリースされたコードの速度を落とすことなく、無駄な冗長なチェックを行うことなく、エラーを早期にキャッチできます。

于 2010-04-08T16:08:01.180 に答える
1

あなた自身のコードでは、多くの用途があるとは思えません。ただし、他の人が使用するライブラリを作成している場合は、ライブラリを使用しているコードにエラーを返す手段として例外を使用する必要があります。

「フレームワークでは、ハードエラーと論理エラーの両方に例外が使用されます。最初は、すべての機能障害を報告する手段として例外処理を採用するのは難しい場合があります。ただし、フレームワークのすべてのパブリックメソッドを次のように設計することが重要です。レポートメソッド-例外をスローして失敗します。」

Krzysztof Cwalina、再利用可能なフレームワークの設計

于 2010-04-08T16:06:52.567 に答える
1

ここで少し誤解を招くタイトルですが、それは(特別な)DivideByZeroExceptionをスローすることではなく、質問です。

ユーザー入力の検証中に例外を使用する必要がありますか?

これはおそらく以前に尋ねられたことがあります。私の見解:いいえ、エラーコードまたはブール値でこれを処理できるフローを使用してください。

ただし、アプリのより深いレイヤーで「データ」を検証する場合、通常、例外をスローするのが正しい方法です。

于 2010-04-08T16:08:44.347 に答える
1

何らかの形式の数値クラスを記述していて、クラスを呼び出すコードが検証を実行することを期待できる場合は、DivisionByZeroExceptionをスローすると便利な場合がありますが、他のほとんどの場合は、操作の前にチェックしてスローする方がよいでしょう。必要に応じて、ArgumentExceptionまたはArgumentOutOfRange例外。

NullReferenceExceptionは、フレームワークが使用する予約済みの例外の1つであり、IndexOutOfRange、AccessViolationException、OutOfMemoryExceptionとともに、パブリックAPIを介してスローしてはなりません。フレームワーク設計ガイドラインの本またはコード分析の警告の説明を参照してください

于 2010-04-08T16:13:29.873 に答える
0

私が考えることができるものはありません。私はそれに対してプログラムするだけです。例外は高額になる可能性があるため、それに対して防御的にプログラムできる場合は、例外をスローする代わりにそれを実行してください。

少なくとも、何ヶ月も前にDivideByZeroExceptionをキャッチしようとしたときに、私の上級開発者が私に言ったことです。

于 2010-04-08T15:51:42.467 に答える
0

データの処理を開始する前に、関数の先頭でこれらのチェックを行うことをお勧めします。むしろ、メソッドの途中でそれらをスローします(または他のメソッドがこれらの例外をスローします)。

于 2010-04-08T15:54:52.363 に答える
0

理論的には(そして実践的にも)、誤ったケースを特定して回避/排除することは、それらを例外として扱うよりも優れています。ただし、コード内のすべてのケースまたはパスをテストできるとは限りません。また、すべてのケースで入力を制御できるわけではありません。

優れた設計の信条は、プログラムに例外的な状況を認識させ、適切に処理させることです。さらに、エラー、特にコードのデプロイ後に発生する可能性のあるエラーを診断するのに十分な情報をユーザー(そして最終的には自分自身)に提供することをお勧めします。したがって、アプリケーションコードがより堅牢になり、診断が容易になるかどうかを示すような例外をスローすることが理にかなっている場合があります

于 2010-04-08T15:59:57.440 に答える
0

doubleの場合、ゼロで除算すると、実際には、分子が正、負、またはゼロのいずれであるかに応じて、double.Infinity、double.NegativeInfinity、またはdouble.NaNの値になることに注意してください。

除算を実行する前に、これらの値がすでにケースに適している可能性があります。そうでない場合は、入力を検証し、それに応じて動作する必要があります。

API(ライブラリなど)を作成していて、ゼロによる除算を許可しないコントラクトを提供したい場合(たとえば、ある種の除算を実行するメソッドを公開する場合)、この例外をスローすることをお勧めします。ただし、通常は、このタイプの例外をプログラムエラーのインジケーターとして予約します。

于 2010-04-08T16:08:45.390 に答える
0

Never(ユーザーが分母として0を送信することはありません)およびalways(ユーザーは常に適切な引数値を提供します)は、コードに含める危険なアイデアです。私たちのごく一部は、他の開発者によって変更されたり呼び出されたりすることのないコードで、単独でプログラムします。したがって、防御的なコードを作成する必要があります。ゼロ除算の場合、適切な結果がどうあるべきかを決定するべきではありません。それは呼び出し元にフォールバックします。例外をスローすることは、問題を返すための合理的な方法のようです。費用はかかりますが、例外のスローを回避するためにコードに追加するインフラストラクチャも費用を追加します。

于 2010-04-08T16:26:31.113 に答える
0

作業をフレームワーク(.NETまたはその他)に依存している場合は、フレームワークに例外をスローさせる必要があります。

これにより、メソッドのコンシューマーが標準的な方法でスローされた例外を処理しやすくなります。

ゼロ除算の場合は、フレームワークと同じロジックを再実装して例外をスローします。

于 2010-04-08T17:04:56.677 に答える
-1

例外をスローすることは、リソースの観点から行うにはコストのかかる作業です。すでに例外の発生を防いでいるのに、なぜ例外をスローするのですか?ユーザーに通知する必要がある場合は、何らかのメッセージングメカニズムを使用してください。自分で知る必要がある場合は、ログに記録してください。

于 2010-04-08T15:53:09.133 に答える