捕捉一般例外情况

根据这篇MSDN文章 ,你不应该抓住一般的例外情况。 我确定有一个stackoverflow问题处理这个问题,我理解为什么它不是一个好的做法,但我今天在另一篇MSDN文章中看到了这个例子:

using System; using System.IO; class Test { public static void Main() { try { using (StreamReader sr = new StreamReader("TestFile.txt")) { String line = sr.ReadToEnd(); Console.WriteLine(line); } } catch (Exception e) { Console.WriteLine("The file could not be read:"); Console.WriteLine(e.Message); } } } 

是否有任何理由在该示例中捕获一般exception,或者只是他们懒得编写一个示例来捕获所有特定exception?

在这种情况下,这是一个例子 ,就像MSDN上的许多代码示例一样。

这应该是捕获IOexception而不是基类。

只要你重新抛出,捕获Exception就有意义的唯一地方是用于日志记录的全局exception处理程序。

示例应该清晰简单。 这是一个清晰简单的例子。 但是我们不应该在代码中捕获一般的例外。

规则“ CA1031:不捕获一般exception类型 ” 完全没用 。 (不是它本身的意图,而是它的实现和描述)

在这种特定情况下 ,捕获更具体的IOException 可能是可行的,因为它涵盖了StreamReader构造函数要记录的“大多数”exception。

(哦等等,然后你还需要考虑ReadToEnd可能抛出的所有东西)

(哦,等等, 也许这是一个合法的exception捕获案例,对于传递的字符串为空的情况有一个ArgumentException – 也就是说,我想要抓住它一般而不是明确地测试它。)

除了那个:

  • 可能从任何函数抛出的exception集是

    1. 往往记录不佳
    2. 可能无限制(可能潜伏一些OutOfMemoryException ;实现中导致其他exception的错误等)
    3. 在很大程度上无关紧要(模仿一些bug,如ArgumentNullException

大致给出了给出的示例, 您所关心的只是读取文件失败 – IFF失败,您需要通过调用链进行通信。

重复:你想要通信读取文件的调用链失败为什么只是次要的。

何时读取(处理)文件失败:何时抛出任何exception。

所以你真正想要做的是抓住任何exception,用你想做的事情(例如,添加文件名)进行上下文化 ,然后返回或重新抛出表明出错的原因以及出错的原因 (那将是实际的“内在的“例外”。

为此, 示例(几乎)指出

  • 在这种情况下,“向上呼叫链”是用户直接在控制台
  • 它将错误“返回”为“用户”要读取的字符串,这适用于简单的consle程序。
  • 它清楚地传达了出错的地方。 (它应该包含传递给StreamReader的文件名。)
  • 它包括它出错的原因,即exception消息。 (它可能还应包括调用堆栈。)

例如:

假设此示例稍微复杂一些,文件名是用户提供的。 然后,字符串为空是(a)正常情况,并且可能是(b)可能不保证代码中的特殊处理的用户错误,因为提供的一般处理 – 即报告读取文件失败 – 是完全够了。

通过按照上面的建议捕获IOException ,输入空文件名的用户会使应用程序崩溃,或者需要一个额外的catch块,它基本上与另一个catch块做同样的事情:报告读取文件失败以及原因。


独立观察:发现这个好文章: http : //www.codeproject.com/Articles/7557/Exception-Handling-in-C-with-the-quot-Do-Not-Catch ,作者肯定比我的建设性更强“完全没用”的陈述,但基本上有一个类似的结论(有一个不同的,当然有效的解决方案):( emph。添加)

如果我们遵循Microsoft的指导原则,那么我们必须只捕获可能由File.Copy方法触发的File.Copy 。 如果你查看.NET Framework的类库,你会发现这是UnauthorizedAccessException,(…)。 如果你问我,单独捕捉所有这些例外是不可行的。 我想知道的是文件副本是否失败。 仅捕获IOException,ArgumentException和NotSupportedException就足够了(因为所有其他exception都来自这三个例外),但要知道这一点,我必须再次阅读文档。 我真的不想轻易复制一个文件。

该指南假设我们知道所执行任务可以抛出的所有exception。 复制文件是一项非常简单的操作,Microsoft已正确记录。 但是,如果我们使用某些第三方工具呢? 我们无人值守工具的稳定性取决于此工具文档的质量。 如果此第三方忘记提及其工具在文档中引发的exception之一,那么我们的无人参与应用程序可能会过早停止。