C#重新抛出异常

6

在多个方法之间抛出异常时,是否应该让所有方法重新抛出异常?例如:

Method1()
{
   Method2();
}

Method2()
{
   try
   {
      // Do something
   }
   catch
   {
      throw;
   }
}

try
{
   Method1();
}
catch
{
   // Do something about exception that was thrown from Method2()
}

请注意,在 Method1() 中,我不需要将 Method2() 包裹在 try 块中,这样做必要吗?
2个回答

9
你不需要把所有东西都放在try块中。
只有当你想要catch某些东西时,才应该使用try,而且只有在以下情况下才应该catch
  • 你已经准备好处理异常(做必须要做的事情,并且不要让它向上传播到堆栈上),
  • 你想对异常做一些事情(例如记录日志)并重新抛出它(使用无参数形式的throw),
  • 你想通过将其包装在自己的另一个异常中来添加异常的详细信息(请参见Allon Guralnek的优秀评论)。

3
+1:简洁准确。我想再补充一个不完全是“重新抛出”的原因——将异常包装在另一个异常中(但始终将原始异常保留在InnerException中,否则您将丢失有关原始异常的信息,这可能有助于调试)。包装可以提供比重新抛出更多的上下文,例如:“无法为客户843保存新订单,请参阅InnerException获取详细信息。” - Allon Guralnek

8
除非您有某些特定原因要首先捕获它们,否则您不需要尝试、捕获和重新抛出异常。否则,它们将自动从抛出它们的较低级别函数冒泡到代码中最高级别的函数。实质上,您可以认为它们一直被“重新抛出”,即使这并不是技术上发生的事情。
事实上,大多数情况下,您看到编写try/catch块时,都是不正确的。除非您确实能够处理异常,否则您不应该捕获异常。捕获异常只是为了重新抛出它们是毫无意义的(事实上被认为是不良实践)。不要在所有的代码中都包含try块。
请注意,“处理它们”的意思是,在catch块中的代码将根据抛出的特定异常采取某些特定操作,以尝试纠正异常条件。
例如,对于FileNotFoundException,您可能会通知用户找不到文件,并要求他们选择另一个文件。

请查看此处我的回答以获取更多详细信息和关于“异常处理最佳实践”的深入讨论。


据我所知,编写catch(Exception ex)是一种不好的做法,更好的方法是捕获一些特定的错误,例如ArgumentNullException或类似的错误。为什么会这样呢?还有一个问题是,为什么每个人都在catch语句的末尾加上throw;?为什么异常应该再次抛出?因为有一些更高级别的处理程序需要捕获和处理它吗? - Roxy'Pro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接