我在理解try-catch-finally的执行顺序时遇到了问题。我见过的所有例子(如:http://stackoverflow.com/questions/4191027/order-of-execution-of-try-catch-and-finally-block)都有一个非常简单的“捕获”部分,打印到控制台。但是如果我在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
根本没有印刷......
或者它只是一种“未定义的行为”?
答案 0 :(得分: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没有打印,因为它之前会抛出异常。由于catch块中的throw
,因此不会打印相同的5. 7。
<强> [/ EDIT] 强>
回答你的问题:答案是:200
答案 1 :(得分:3)
从评论到另一个答案的流行需求:
它将立即执行throw。所以catch块中的任何代码 投掷后不会被执行。但是,它会执行 最后在将抛出的异常传递给相应的之前 父节点。
原始回答
您的代码将执行try块。如果成功,它将运行finally块。它会结束。
如果try块在某处抛出异常,那么它将立即停止在该点执行并开始执行catch块(假设捕获了异常类型)。一旦catch块执行完毕,它将执行finally块。然后在这种情况下,它将在堆栈中传播抛出的错误。
编辑添加:是的,它将打印200作为答案,因为最终是最后一部分运行,在你的catch块重置答案之后。
答案 2 :(得分:2)
最简单的测试方法是尝试一下。它应该打印 - 答案是200,然后出错。
最后将始终被调用(除了一些无法捕获的异常,例如堆栈溢出)。您应该注意尝试不要在finally块中抛出异常......
您的流程将是:
exception caused
caught
answer variable set
exception thrown
finally block executed
exception propogated up the stack
答案 3 :(得分:0)
很难解释,但通常在退出范围(在您的情况下是堆栈框架)时,finally子句将执行。