.NET Framework 捕获并重新抛出捕获的异常

示例

当您想捕获异常并执行某些操作,但是由于异常而导致您无法继续执行当前代码块时,您可能需要将该异常重新扔到调用堆栈中的下一个异常处理程序中。有好办法,也有坏办法。

private static void AskTheUltimateQuestion()
{
    try
    {
        var x = 42;
        var y = x / (x - x); // 将抛出DivideByZeroException

        // 重要说明:以下字符串格式的错误是故意的
        // 并且存在向FormatException捕获抛出异常,如下所示
        Console.WriteLine("The secret to life, the universe, and everything is {1}", y); 
    }
    catch (DivideByZeroException)
    {
        // 我们不需要引用该异常
        Console.WriteLine("除以零会破坏宇宙。");

        // 这样做以保留堆栈跟踪:
        throw;
    }
    catch (FormatException ex)
    {
        // 仅在需要更改要引发的异常类型时才这样做 
        // 并包装内部异常

        // 请记住,外部Exception的堆栈跟踪将指向
        // 下一行

        // 您需要检查InnerException属性以获取堆栈跟踪
        // 到真正开始出现问题的那一行

        throw new InvalidOperationException("观看格式字符串索引。", ex);
    }
    catch (Exception ex)
    {
        Console.WriteLine("Something else horrible happened. The exception: " + ex.Message);

        // 不要这样做,因为堆栈跟踪将更改为指向
        // 此位置而不是例外的位置
        // 最初被抛出:
        throw ex; 
    }
}

static void Main()
{
    try
    {
        AskTheUltimateQuestion();
    }
    catch
    {
        // 如果您不需要有关任何信息,请选择这种渔获 
        // 被捕获的异常

        // this block "eats" all exceptions instead of rethrowing them
    }
}

您可以按异常类型甚至按异常属性进行过滤(C#6.0中的新增功能,VB.NET(需要引用)中可用的时间更长):

文档/ C#/新功能