-2

try-catch-finallyの実行順序を理解するのに問題があります。私が見たすべての例(http://stackoverflow.com/questions/4191027/order-of-execution-of-try-catch-and-finally-blockのように)には、非常に単純な「キャッチ」部分があります。コンソールに印刷します。しかし、キャッチで「throw」ステートメントを使用するとどうなりますか?

私が考えることができる最も単純なコードは、問題を捉えています。

public class TestClass
{
    void Foo(int num)
    {
        int answer = 100;
        try
        {
            answer = 100 / num;
        }
        catch (Exception e)
        {
            //Probably num is 0
            answer = 200;
            throw;
        }
        finally
        {
            Console.WriteLine("The answer is: " + answer);
        }
    }
}

num == 2の場合、出力は次のようになります。

答えは:50

しかし、num == 0の場合は何が出力されますか?

答えは次のとおりです。100
答えは次のとおりです。200
印刷はまったくありません...

それとも単なる「未定義動作」ですか?

4

4 に答える 4

5

tryブロック内で例外が発生した場合、catchブロック内のコードが実行されます。複数のcatchブロックがある場合、catchされた例外に最もよく一致するものが除外されます。

class A : System.Exception {}
class B : A {}

void Test()
{
    try
    {
        throw new B();
    }
    catch (A a)
    {
        //as B is derived from A, this catch block will be invoked.
    }
    catch (Exception e)
    {
    }
}

結局、finallyブロックが実行されます。例外が発生したかどうかは関係ありません。

[編集] 順序をもう少し明確にするために(コメントのおかげで)

void Test()
{
    Debug.WriteLine("1");
    try
    {
        Debug.WriteLine("2");
        throw new Exception();
        Debug.WriteLine("3");
    }
    catch
    {
        Debug.WriteLine("4");
        throw;
        Debug.WriteLine("5");
    }
    finally
    {
        Debug.WriteLine("6");
    }
    Debug.WriteLine("7");
}

印刷されるものは次のとおりです。

1 2 4 6

3は、その前に例外siがスローされるため、出力されません。throwキャッチブロック内にあるため、5.7についても同じです。

[/編集]

だからあなたの質問に答える:答えは:200

于 2011-10-25T15:30:43.873 に答える
3

コメントから別の回答への一般的な要求によって:

すぐにスローを実行します。したがって、スロー後のcatchブロック内のコードは実行されません。ただし、スローされた例外を適切な親に渡す前に、finallyを実行します。

元の回答

コードはtryブロックを実行します。これが正常に成功すると、finallyブロックが実行されます。その後、終了します。

tryブロックがどこかで例外をスローした場合、その時点ですぐに実行を停止し、catchブロックの実行を開始します(例外タイプがキャッチされていると想定)。catchブロックの実行が完了すると、finallyブロックが実行されます。次に、この場合、スローされたエラーをスタックに伝播します。

追加するために編集:はい、キャッチブロックが回答をリセットした後、ファイナルが実行する最後の部分であるため、回答として200が出力されます。

于 2011-10-25T15:32:51.453 に答える
2

テストする最も簡単な方法は、それを試すことです。印刷する必要があります-答えは200で、その後エラーになります。

最後に常に呼び出されます(スタックオーバーフローなど、キャッチできない一部の例外を除く)。finallyブロック内から例外をスローしないように注意する必要があります...

ここであなたの流れは次のようになります:

exception caused
caught
answer variable set
exception thrown
finally block executed
exception propogated up the stack
于 2011-10-25T15:31:52.210 に答える
0

説明するのは難しいですが、通常、スコープ(この場合はスタックフレーム)が終了すると、finally句が実行されます。

于 2011-10-25T15:31:36.853 に答える