0

「例外」のようなエラーをトラップするのではなく、開発者として予想されるエラーをトラップするようにアドバイスされるのはなぜですか。一般的なエラーのトラップでパフォーマンスが低下しますか、それともベストプラクティスの観点から推奨されますか?

  try
  {
        // Do something
  }
  catch(Exception e)
  {
        //Log error
  }
4

6 に答える 6

9

ベストプラクティスは、最初に特定の例外をキャッチしてから、より一般的な例外に進むことです。

例外処理(C#プログラミングガイド)

異なる例外フィルターを持つ複数のcatchブロックをチェーン化できます。キャッチブロックはコードで上から下に評価されますが、スローされる例外ごとに1つのキャッチブロックのみが実行されます。スローされた例外の正確なタイプまたは基本クラスを指定する最初のcatchブロックが実行されます。一致する例外フィルターを指定するcatchブロックがない場合、ステートメントにフィルターが存在する場合は、フィルターを持たないcatchブロックが選択されます。最も具体的な(つまり、最も派生した)例外タイプを持つキャッチブロックを最初に配置することが重要です。

あなたの質問のために:

「例外」のようなエラーをトラップするのではなく、開発者として予想されるエラーをトラップするようにアドバイスされるのはなぜですか。

例として、NullReferenceExceptionをキャッチします。NullReferenceExceptionをキャッチすることは決して良い習慣ではありません。代わりに、インスタンスメンバーを使用する前に、オブジェクトがnullであることを常に確認する必要があります。たとえば、文字列の場合。

string str = null;
try
{
   Console.WriteLine(str.Length)
}
catch(NullReferenceException ne)
{
    //exception handling. 
}

代わりに、nullをチェックするためのチェックを行う必要があります。

if(str != null)
   Console.WriteLine(str.Length);

編集:

質問が間違っていると思います。どの例外をキャッチする必要があり、どの例外をキャッチしないかを尋ねる場合は、処理できる例外をキャッチして、残りをライブラリに残して、上位にバブルアップできるようにする必要があります。適切な処理が行われるレイヤー。例として、主キー制約の違反があります。アプリケーションがユーザーから入力(主キーを含む)を取得し、その日付がデータベースに挿入されている場合、その例外をキャッチして、ユーザーに「レコードは既に存在します」というメッセージを表示して、ユーザーに入力させることができます。異なる値。

ただし、例外が外部キー制約に関連している場合(たとえば、ドロップダウンリストの一部の値が無効な外部キーと見なされる場合)、その例外はバブルアップし、汎用例外ハンドラーが適切な場所に記録する必要があります。

たとえば、ASP.Netアプリケーションでは、これらの例外をApplication_Errorイベントに記録し、一般的なエラーページをユーザーに表示できます。

編集2: OPのコメントについて:

エラーがsqlexceptionであるかどうかを認識しているにもかかわらず、一般的なエラーをキャッチする際にパフォーマンスが低下する場合は、低レベルの場合

パフォーマンスに違いが生じたとしても、無視できるはずです。ただし、例外が発生することがわかっている場合は、特定の例外をSqlExceptionキャッチします。

于 2013-02-06T10:42:00.473 に答える
4

処理できる例外のみをキャッチする必要があります。Exceptionあまりにも一般的であるため、ほとんどの場合、それを処理できるとは言えません。少しおかしいですが、例外をキャッチする必要があります:)

捕まえる必要Exceptionがあるがまれな状況があり、ほとんどの場合それを避ける必要があります。通常、これは何らかの設計上の問題を示しています。

于 2013-02-06T10:43:36.007 に答える
2

例外を処理する最良の方法については、 Eric Lippertのブログ(Vexing例外)を確認してください。

•致命的な例外をキャッチしないでください; とにかくそれらについてあなたができることは何もありません、そして一般的にそれを悪化させようとします。

•骨の折れる例外がトリガーされないようにコードを修正します。「インデックスが範囲外」の例外が本番コードで発生しないようにします。

•例外的でない状況でスローする厄介なメソッドの「Try」バージョンを呼び出すことにより、可能な限り厄介な例外を回避します。厄介なメソッドの呼び出しを避けられない場合は、その厄介な例外をキャッチします。

•予期しない外因性の状態を示す例外を常に処理します。一般に、考えられるすべての障害を予測することは価値がなく、実用的でもありません。操作を試して、例外を処理する準備をしてください。

于 2013-02-06T11:24:35.730 に答える
1

必要以上に頻繁に例外処理を使用することは、実際には何よりも怠惰なプログラミング方法です。がありDataTable、最初の行にアクセスしたいとします。

public DataRow AccessFirstRow(DataTable dt)
{
  try
  {
    return dt.Rows[0];
  }
  catch (Exception e)
  {
    //There isn't a first row or dt is null
  }
}

それ以外の

public DataRow AccessFirstRow(DataTable dt)
{
  if(dt != null)
   if(dt.Rows.Count > 0)
     return dt.Rows[0];
  //If we can't access dt, then don't
  return null;
}

私の経験則は次のとおりです。

例外は、例外的な状況でのみ使用する必要があります。

ただし、前述のように、一般的な例外の代わりに発生する可能性のある特定の例外を処理することにした場合は、それらを処理することにします。

于 2013-02-06T10:46:34.570 に答える
1

これはベストプラクティスです。予期しない例外はより重大な/基本的なエラーによって引き起こされる可能性があるため、プログラムの上位にあるより一般的な例外を使用しながら、既知の例外を明示的に迅速に処理する必要があります。

于 2013-02-06T10:46:36.000 に答える
1

処理する予定の例外をキャッチします。通常、報告されたエラー(クリーンアップに使用されるオブジェクトへのアクセスなど)を処理するための十分な情報があるコンテキスト(メソッド)で特定の例外を処理する必要があります。

ブロック内のコードtryが異なるタイプの例外をスローする場合、同じメソッド内でいくつかの例外を処理し、呼び出し元のメソッドでそれらを処理するために他の例外を再スローすることができます(そのコンテキストでは、それらの例外を処理するためのリソースがあります)。

于 2013-02-06T10:53:32.733 に答える