-2

我在理解 try-catch-finally 的执行顺序时遇到问题。我见过的所有示例(例如:http://stackoverflow.com/questions/4191027/order-of-execution-of-try-catch-and-finally-block)都有一个非常简单的“catch”部分打印到控制台。但是如果我在 catch 中使用“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 块,则执行与捕获的异常最匹配的那个。

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 未打印,因为在它之前抛出了异常。5. 7 也一样,因为throw在 catch 块中,所以不会打印。

[/编辑]

所以回答你的问题:答案是:200

于 2011-10-25T15:30:43.873 回答
3

根据评论对另一个答案的普遍要求:

它将立即执行抛出。所以 throw 之后的 catch 块中的任何代码都不会被执行。但是,它会在将抛出的异常传递给适当的父级之前执行 finally。

原始答案

您的代码将执行 try 块。如果成功,它将运行 finally 块。然后它将结束。

如果 try 块在某处抛出异常,那么它将立即停止执行并开始执行 catch 块(假设异常类型被捕获)。一旦 catch 块执行完毕,它将执行 finally 块。然后在这种情况下,它将在堆栈中传播抛出的错误。

编辑添加:是的,它将打印 200 作为答案,因为在您的 catch 块重置答案之后,final 是运行的最后一部分。

于 2011-10-25T15:32:51.453 回答
2

最简单的测试方法是尝试一下。它应该打印 - 答案是 200,然后出错。

finally 总是会被调用(除了一些不能被捕获的异常,例如堆栈溢出)。您应该注意尝试不要从 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 回答