捕捉一般例外情况

时间:2012-10-12 09:28:17

标签: c# exception exception-handling

根据this MSDN article,你不应该抓住一般例外。我确定有一个stackoverflow问题处理这个问题,我理解为什么这不是一个好习惯,但我今天在another MSDN article看到了这个例子:

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);
        }
    }
}

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

3 个答案:

答案 0 :(得分:2)

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

这应该是捕获IO Exception而不是基类。

只要你重新抛出,捕获Exception的唯一地方就是在日志记录的全局异常处理程序中。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

规则“ CA1031:不捕获常规异常类型”是utterly useless。 (不是它本身的意图,而是它的实现和描述)

在这个特定情况下 可能可以捕捉更具体的IOException,因为它涵盖了StreamReader constructor的“大部分”例外情况记录下来。

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

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

除此之外:

  • 可以从任何函数抛出可能的异常集

    1. 通常记录不清
    2. 可能无限制(可能潜伏一些OutOfMemoryException;实施中导致其他异常等的错误。)
    3. 在很大程度上无关紧要(以ArgumentNullException
    4. 之类的方式模仿某些错误

鉴于粗略给出的示例,您所关心的只是读取文件失败 - IFF失败,您需要通过调用链进行通信。

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

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

所以你真正想要做的就是捕获任何异常,用你想做的事情(例如,添加文件名)进行上下文化,然后返回或重新抛出指示 what < / em>出错并且为什么出错了(这将是实际的“内部”异常)。

为此,该示例(几乎)点

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

以示例:

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

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


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

  

如果我们遵循微软的指导方针,那么我们只能抓住那些   可以由File.Copy方法触发的异常。如果你   看看.NET Framework的类库,你会看到这是   UnauthorizedAccessException,(...)。 如果你   问我,单独捕捉所有这些例外是不可行的。所有   我想知道文件副本是否失败。它会   足以只捕获IOException,ArgumentException和   NotSupportedException(因为所有其他异常派生自   这三个例外)但知道这个我必须阅读   文档。我真的不想经历那么多   简单地复制文件很麻烦。

     

指南假设我们知道所有可能的例外情况   被执行的任务抛出。复制文件是一项非常简单的操作   这是由Microsoft正确记录的。但是如果我们使用一些东西呢?   第三方工具?我们无人值守工具的稳定性取决于   该工具文档的质量。如果这个第三方忘了   提到他们的工具抛出的一个例外   文档,然后我们无人值守的应用程序可能会提前停止。