在C#中,我如何知道要捕获哪些异常?

时间:2010-04-28 13:57:30

标签: c# exception exception-handling try-catch

我养成了使用常规catch语句的习惯,并且我以一般方式处理这些异常。这是不好的做法吗?如果是这样,我怎么知道可以抛出哪些特定的异常以及我捕获哪些异常?

11 个答案:

答案 0 :(得分:18)

  1. 是的,除了一些非常具体的情况,这是不好的做法。我可以想到捕获所有异常的一个常见情况并不是一个糟糕的想法,就是在应用程序即将崩溃之前记录消息或堆栈跟踪(或者,也许,您正在记录和重新抛出)。

  2. 仅捕获您知道可以处理的异常。不多也不少。如果您不知道可以从方法抛出异常,那么您无论如何都不会正确处理它,所以不要抓住它。方法和库负责记录您应该能够处理的异常。另外,不要捕获表示逻辑失败的异常,例如NullReferenceExceptionArgumentException。这些表明您应该修复的软件中存在真正的错误,而不是您应该在运行时处理的错误。

答案 1 :(得分:5)

是的,这是不好的做法。经验法则:“抓住你能够回应的例外,让其他人去做。”

try {
    File.Open(usersChosenFile, FileMode.Open);
} catch(FileNotFoundException) {
    // tell the user the file is gone, give them a chance to respond
    // this is good
} catch(UnauthorizedAccessException) {
    // this is good too
} catch(Exception) {
    // what did you just catch? Who knows. What if its OutOfMemoryException?
    // Do you really want to deal with that here? Let this one go by
}

答案 2 :(得分:3)

您运行的方法通常会显示可以抛出的异常。然后你可以相应地抓住。

如果它是您自己的代码,您通常可以看到将抛出的内容,或使用基础类异常作为您需要捕获的内容的指南。

我推荐一些链接:

答案 3 :(得分:2)

更大的问题是,您是否需要针对特定​​异常进行特定的错误处理。如果您只需捕​​获发生的任何错误,那么只需创建一个通用的try / catch块就没有错误:

try
{
    // Some Code
}
catch
{
}

但是,如果您需要对某些异常进行特定处理,则可以在每次尝试时指定多个catch块:

try
{
    // Some Code
}
catch(ArgumentException argE)
{
}
catch(NullReferenceException nullE)
{
}
catch(Exception e)
{
    // Everything else
}

如果您无法从异常中恢复,请不要在该级别捕获它。

答案 4 :(得分:1)

IMO - 除非您计划为其添加值和/或只能以该方法处理,否则不会捕获任何异常。

请确实有一个常见的异常处理程序来处理所有未处理的异常。

HTH。

答案 5 :(得分:1)

正如Kyle所说,让你的方法长度很小,只在小范围内放置try / catch。将鼠标悬停在您调用的方法上 - 然后您应该获得一个例外列表。 这不会捕获列出的每个异常,但如果您在catch (Exception e) { ... }内打印异常类型,也可以凭经验发现异常。您所追求的是e.GetType().FullNamee.StackTrace以及e.Messagee.InnerException ...或我列出的内容的一部分。

答案 6 :(得分:0)

使用框架方法时,可以查看MSDN文档。每个方法描述都有一个可能抛出的异常列表。

例如,请查看File.Open()文档中的例外段落。

使用自己的方法时,应该了解方法可能抛出的异常。

答案 7 :(得分:0)

文档通常会描述方法可能抛出的异常以及可能发生的条件。对于.NET框架的Microsoft参考文档尤其如此。

在我看来,只有在你有充分的理由抓住它们时才应该抓住例外。这通常意味着不必以通用方式捕获和处理它们。记录异常(异常处理程序中的一个非常常见的活动)应该只发生在调用堆栈的底部,或者只要你不重新抛出(可能包装的)异常,这应该是罕见的。如果你想要在调用堆栈中的每一帧都有一些动作,当一个例外正在冒泡时,请看一下面向方面编程(AOP)技术。

答案 8 :(得分:0)

除了在极少数情况下,我通常认为catch块是代码味道。

通过事先检查条件来防止抛出异常。例如,如果从文件读取,则使用System.IO中的类来检查文件是否存在,而不是使用catch块来处理文件不存在的情况。

Catch块不应构成应用程序逻辑的一部分。

答案 9 :(得分:0)

您应该抓住那些可以制定合理策略来处理问题的例外情况。如果没有合理的替代方案,那么抓住异常是没有意义的(稍后再尝试,使用不同的技术/技术来实现相同的总体目标,通知用户目前无法实现目标以及他们可以做些什么来补救情况)。

异常(原谅):值得在最高级别(例如Application.ThreadException或AppDOmain.UnhandledException)使用某些东西来尝试记录那些尚未处理的异常。如果记录失败,你无论如何都会注定失败。

但盲目地吞下所有异常(特别是在低级别)会导致非常令人沮丧的调试/诊断会话。

答案 10 :(得分:0)

您必须做出设计决定,确定您是否真的需要在代码中捕获所有异常。我知道捕捉Exception有意义的两个条件:

  • 如果您绝对不允许异常冒泡并终止您的应用程序。
  • 调用代码期望您的方法/属性抛出异常,因为它是原子事务。在这种情况下,您将捕获所有异常并安全返回。

捕获所有异常的缺点是屏蔽可能有用的错误消息并忽略它,从而在您的应用程序中造成意外的副作用。