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