可能性のある複製:
入れ子のTry/Catchは悪いアイデアをブロックしていますか?
現在、try catch内でtry catchを使用していますか?現在のシナリオでは、アプリケーションでそれが必要です。
void MyFun()
{
try
{
//Process logic 1
// ......
try
{
//Process logic 2
// ......
} catch (Exception ex)
{
//write an error details in database
}
//Process Logic 3
// ......
} catch (Exception ex)
{
//show error msg
}
}
特に例外を別の方法で処理する場合は、特に問題はありません。
ただし、内部例外と外部例外のタイプがそれぞれE1, E2
であり、E1
がE2
の親ではない場合、2つの隣接するcatch句を持つことができます。
try
{
// do something
}
catch (E1 e1)
{
}
catch (E2 e2)
{
}
RobとJ.Steenが指摘したように、この場合はE1
が実行されない後にコードがスローされるため、これは質問の場合とは少し異なります。
この項目は、それが悪いことではなく、エラーを別の方法で処理するだけでよいことを示しています。
なぜかわかりません。失敗したり、処理を必要とする例外を発生させたりする可能性のあるキャッチ内のロジックがある場合、それは理にかなっています。
ネストされたtry/catchは問題ありません。避けたいのは、try catchに基づいてコードの論理フローを変更することです。つまり、try/catchをif/elseブロックとして扱わないでください。これは理想的ではありません:
//over the top example just to demonstrate my point
public bool IsNumberTen(int x)
{
try
{
if(x > 10)
throw new NumberTooHighException();
else if(x < 10)
throw new NumberTooLowException();
else
return true;
}
catch(NumberTooHighException)
{
return false;
}
catch(NumberTooLowException)
{
return false;
}
}
ここにどのようなロジックがあるのかを知らずにこの質問に答えるのは少し難しいです。確かにパフォーマンスの点では、ネストされた例外処理はコストが高くなりますが、一般的な経験則では、開発者が処理方法を理解している例外のみをキャッチします。これはTDDの実践と重複しており、十分なテストのセットがあれば、予想される例外がどこにあるかを特定できるため、例外ロジックが決まります。
私はこれを言うでしょう:それは悪くありません。それがgoodであるかどうかはプログラムに依存し、そのような概念がメソッドのロジックとコントラクトを考慮して意味があるかどうかに依存します。
編集:記事をチェックすることをお勧めします 例外コスト:スローするタイミングとしないタイミング 。 CLRでの例外管理に最もコストがかかるものについて概説します。
ネストされたブロックが必要な状況を考えようとしています...おそらく、データベースを変更していて、仮想トランザクションとしてtry catchを使用している場合、いくつかのプロパティを更新してみてください。これは失敗しますが、実際にデータベースの更新自体をコミットする場合は、全体的な例外もキャッチします。
これを考慮しても、これを行う必要はありません...ブロックを次のように単純に互いに積み重ねるだけで十分です:
void MyFun()
{
try
{
//Process logic 1
// ......
} catch (Exception ex)
{
//show error msg
}
try
{
//Process logic 2
// ......
} catch (Exception ex)
{
//write an error details in database
}
}
また、catchブロックをネストする必要がある場合は、コードを設計するより良い方法があることにも注意してください。
編集: Itayの答えもネストよりもいくらか優れていますが、例外をキャッチすると、ブロックを続行できなくなります。
お役に立てれば!