21

かなり単純に見えるかもしれない質問があります(もちろん、あなたが答えを知っているなら)。

ある関数が別の関数を呼び出していますが、呼び出し先が例外をスローした場合でも、呼び出し元から実行を継続したいと思います。例を挙げましょう:

something function1()
{
    try
    {
        //some code
        int idNumber = function2();
        //other code that need to execute even if function2 fails
        return something;
    }
    catch(Exception e)
    {//... perhaps something here}
}

編集:function1にはreturnステートメントもあるので、途中で実際にクラッシュすることはありません

function2では、何かをする必要がありますが、何かが失敗した場合にのみログに記録する必要があります。例:

int function2()
{
    try
    {
        //dostuff
    }
    catch(Exception e)
    {
        //Log stuff to db
    }
}

さて、私の質問は、関数2がエラーをスローした場合でも、関数1で実行を続行したい場合はどうすればよいですか?

投げる必要がある場合、時々私は混乱します。またはeを投げます。または何もスローしません(キャッチブロックを空のままにします)

4

6 に答える 6

26

キャッチブロックを空のままにしておくと、うまくいくはずです。ただし、これはほとんどの場合悪い考えです。一方ではパフォーマンスの低下があり、他方では(そしてこれはより重要です)、いつエラーが発生したかを常に知りたいと思うでしょう。

あなたの場合、「呼び出し先」機能が失敗することは、いわば「エラー」であるとは限らないと思います。つまり、時々失敗することが予想されます。この場合、例外を使用するよりも、ほとんどの場合、それを処理するためのより良い方法があります。

ただし、駄洒落を許すなら、「ルール」には例外があります。たとえば、function2がページに実際に結果が必要ではないWebサービスを呼び出す場合、この種のパターンは問題ない可能性があります。ただし、ほぼ100%の場合、少なくともどこかにログを記録する必要があります。このシナリオでは、それをfinallyブロックに記録し、サービスが戻ったかどうかを報告します。現在は価値がないかもしれないようなデータは、後で価値が高くなる可能性があることを忘れないでください。

最後の編集(おそらく):

コメントで、私はあなたがfunction2の中にtry/catchを置くことを提案しました。私が詳しく説明すると思っただけです。Function2は次のようになります。

public Something? function2()
{
    try
    {
        //all of your function goes here
        return anActualObjectOfTypeSomething;
    }
    catch(Exception ex)
    {
        //logging goes here
        return null;
    }
}

そうすれば、null許容の戻り型を使用するため、nullを返しても問題はありません。

于 2012-05-30T16:16:02.793 に答える
10

finally ブロックを使用できないのはなぜですか?

お気に入り

try {

} catch (Exception e) {

  // THIS WILL EXECUTE IF THERE IS AN EXCEPTION IS THROWN IN THE TRY BLOCK

} finally { 

 // THIS WILL EXECUTE IRRESPECTIVE OF WHETHER AN EXCEPTION IS THROWN WITHIN THE TRY CATCH OR NOT

}

質問が修正された後の編集:

できるよ:

int? returnFromFunction2 = null;
    try {
        returnFromFunction2 = function2();
        return returnFromFunction2.value;
        } catch (Exception e) {

          // THIS WILL EXECUTE IF THERE IS AN EXCEPTION IS THROWN IN THE TRY BLOCK

        } finally { 

        if (returnFromFunction2.HasValue) { // do something with value }

         // THIS WILL EXECUTE IRRESPECTIVE OF WHETHER AN EXCEPTION IS THROWN WITHIN THE TRY CATCH OR NOT

        }
于 2012-05-30T16:17:21.140 に答える
6

または、ループロジック自体をtrycatchにカプセル化することもできます。

for(int i = function2(); i < 100 /*where 100 is the end or another function call to get the end*/; i = function2()){

    try{
     //ToDo
    }
    catch { continue; }    

}

または...

try{ 
    for(int i = function2(); ; ;) {
        try { i = function2(); return; } 
        finally { /*decide to break or not :P*/continue; } }
} catch { /*failed on first try*/ } finally{ /*afterwardz*/ }
于 2012-05-30T16:16:45.340 に答える
1

これを行うだけです

    try
    {
        //some code
     try
     {
          int idNumber = function2();

     }
     finally
     {
       do stuff here....
     }
    }
    catch(Exception e)
    {//... perhaps something here}

すべての意図と目的のために、finallyブロックは常に実行されます。現在、実際には実行されない例外がいくつかあります。プログラムを強制終了するタスクと、アプリケーションを即座に強制終了する高速失敗セキュリティ例外です。それ以外は、関数2で例外がスローされ、finallyブロックは必要なコードを実行してから、外側のcatchブロックで例外をキャッチします。

于 2012-05-30T16:15:33.353 に答える
0

function2 が例外をスローしたかどうかに関係なく、function1 でコードを実行したいということですか? 最終ブロックを見ましたか?http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx

于 2012-05-30T16:19:40.473 に答える
0

2 番目の関数で、catch ブロックの e 変数を削除してから、throw を追加します。

これにより、生成された例外が最終関数に引き継がれ、出力されます。

ビジネスロジックコードで例外をスローしたくないが、UI をスローしたくない場合に非常に一般的です。

于 2012-05-30T16:20:05.767 に答える