根据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);
}
}
}
是否有任何理由在该示例中捕获一般异常,或者只是他们懒得编写一个示例来捕获所有特定异常?
答案 0 :(得分:2)
在这种情况下,这是一个示例并且很差,就像MSDN上的许多代码示例一样。
这应该是捕获IO Exception而不是基类。
只要你重新抛出,捕获Exception
的唯一地方就是在日志记录的全局异常处理程序中。
答案 1 :(得分:0)
示例应该清晰简单。这是一个清晰简单的例子。但是我们不应该在我们的代码中捕获一般的例外。
答案 2 :(得分:0)
规则“ CA1031:不捕获常规异常类型”是utterly useless。 (不是它本身的意图,而是它的实现和描述)
在这个特定情况下 可能可以捕捉更具体的IOException
,因为它涵盖了StreamReader
constructor的“大部分”例外情况记录下来。
(哦等等,然后你还要考虑ReadToEnd
可能抛出的所有东西)
(哦,等等,也许这是一个合法的异常捕获案例,对于传递的字符串为空的情况有一个ArgumentException
- 也就是说,我想要一般地捕获它而不是明确地测试它。)
除此之外:
可以从任何函数抛出可能的异常集
OutOfMemoryException
;实施中导致其他异常等的错误。)ArgumentNullException
鉴于粗略给出的示例,您所关心的只是读取文件失败 - IFF失败,您需要通过调用链进行通信。
重复:您想要通信读取文件失败的调用链和为什么只是次要的。
何时读取(处理)文件失败:何时抛出任何异常。
所以你真正想要做的就是捕获任何异常,用你想做的事情(例如,添加文件名)进行上下文化,然后返回或重新抛出指示 what < / em>出错并且为什么出错了(这将是实际的“内部”异常)。
为此,该示例(几乎)点:
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正确记录的。但是如果我们使用一些东西呢? 第三方工具?我们无人值守工具的稳定性取决于 该工具文档的质量。如果这个第三方忘了 提到他们的工具抛出的一个例外 文档,然后我们无人值守的应用程序可能会提前停止。