如果finally块抛出异常,到底会发生什么?
具体来说,如果在finally块中途抛出异常会发生什么。这个块中的其余语句(之后)是否被调用?
我知道异常会向上传播。
如果finally块抛出异常,到底会发生什么?
具体来说,如果在finally块中途抛出异常会发生什么。这个块中的其余语句(之后)是否被调用?
我知道异常会向上传播。
当前回答
它抛出一个异常;)您可以在其他catch子句中捕获该异常。
其他回答
public void MyMethod()
{
try
{
}
catch{}
finally
{
CodeA
}
CodeB
}
CodeA和CodeB抛出的异常的处理方式是相同的。
finally块中抛出的异常没有任何特殊含义,将其视为代码B抛出的异常。
传播异常。
它抛出一个异常;)您可以在其他catch子句中捕获该异常。
对于这样的问题,我通常在Visual Studio中打开一个空的控制台应用程序项目,并编写一个小示例程序:
using System;
class Program
{
static void Main(string[] args)
{
try
{
try
{
throw new Exception("exception thrown from try block");
}
catch (Exception ex)
{
Console.WriteLine("Inner catch block handling {0}.", ex.Message);
throw;
}
finally
{
Console.WriteLine("Inner finally block");
throw new Exception("exception thrown from finally block");
Console.WriteLine("This line is never reached");
}
}
catch (Exception ex)
{
Console.WriteLine("Outer catch block handling {0}.", ex.Message);
}
finally
{
Console.WriteLine("Outer finally block");
}
}
}
当您运行程序时,您将看到执行catch和finally块的确切顺序。请注意,在抛出异常后,finally块中的代码将不会被执行(事实上,在这个示例程序中,Visual Studio甚至会警告你,它已经检测到不可访问的代码):
Inner catch block handling exception thrown from try block. Inner finally block Outer catch block handling exception thrown from finally block. Outer finally block
额外的评论
正如Michael Damatov指出的,try块中的异常如果不在(内部)catch块中处理,就会被“吃掉”。事实上,在上面的例子中,重新抛出的异常并没有出现在外层catch块中。为了更清楚地说明这一点,请看下面稍作修改的示例:
using System;
class Program
{
static void Main(string[] args)
{
try
{
try
{
throw new Exception("exception thrown from try block");
}
finally
{
Console.WriteLine("Inner finally block");
throw new Exception("exception thrown from finally block");
Console.WriteLine("This line is never reached");
}
}
catch (Exception ex)
{
Console.WriteLine("Outer catch block handling {0}.", ex.Message);
}
finally
{
Console.WriteLine("Outer finally block");
}
}
}
正如你可以从输出中看到的,内部异常被“丢失”(即被忽略):
Inner finally block Outer catch block handling exception thrown from finally block. Outer finally block
如果finally块抛出异常,到底会发生什么?
该异常向外和向上传播,并且将(可以)在更高的级别进行处理。
finally块在抛出异常之后将不会完成。
如果finally块是在处理之前的异常期间执行的,那么第一个异常将丢失。
c# 4语言规范§8.9.5:如果finally块抛出另一个异常,则当前异常的处理将终止。