我养成了使用常规catch语句的习惯,并且我以一般方式处理这些异常。这是不好的做法吗?如果是这样,我怎么知道可以抛出哪些特定的异常以及我捕获哪些异常?
答案 0 :(得分:18)
是的,除了一些非常具体的情况,这是不好的做法。我可以想到捕获所有异常的一个常见情况并不是一个糟糕的想法,就是在应用程序即将崩溃之前记录消息或堆栈跟踪(或者,也许,您正在记录和重新抛出)。
仅捕获您知道可以处理的异常。不多也不少。如果您不知道可以从方法抛出异常,那么您无论如何都不会正确处理它,所以不要抓住它。方法和库负责记录您应该能够处理的异常。另外,不要捕获表示逻辑失败的异常,例如NullReferenceException
和ArgumentException
。这些表明您应该修复的软件中存在真正的错误,而不是您应该在运行时处理的错误。
答案 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().FullName
和e.StackTrace
以及e.Message
和e.InnerException
...或我列出的内容的一部分。
答案 6 :(得分:0)
答案 7 :(得分:0)
文档通常会描述方法可能抛出的异常以及可能发生的条件。对于.NET框架的Microsoft参考文档尤其如此。
在我看来,只有在你有充分的理由抓住它们时才应该抓住例外。这通常意味着不必以通用方式捕获和处理它们。记录异常(异常处理程序中的一个非常常见的活动)应该只发生在调用堆栈的底部,或者只要你不重新抛出(可能包装的)异常,这应该是罕见的。如果你想要在调用堆栈中的每一帧都有一些动作,当一个例外正在冒泡时,请看一下面向方面编程(AOP)技术。
答案 8 :(得分:0)
除了在极少数情况下,我通常认为catch块是代码味道。
通过事先检查条件来防止抛出异常。例如,如果从文件读取,则使用System.IO中的类来检查文件是否存在,而不是使用catch块来处理文件不存在的情况。
Catch块不应构成应用程序逻辑的一部分。
答案 9 :(得分:0)
您应该抓住那些可以制定合理策略来处理问题的例外情况。如果没有合理的替代方案,那么抓住异常是没有意义的(稍后再尝试,使用不同的技术/技术来实现相同的总体目标,通知用户目前无法实现目标以及他们可以做些什么来补救情况)。
异常(原谅):值得在最高级别(例如Application.ThreadException或AppDOmain.UnhandledException)使用某些东西来尝试记录那些尚未处理的异常。如果记录失败,你无论如何都会注定失败。
但盲目地吞下所有异常(特别是在低级别)会导致非常令人沮丧的调试/诊断会话。
答案 10 :(得分:0)
您必须做出设计决定,确定您是否真的需要在代码中捕获所有异常。我知道捕捉Exception
有意义的两个条件:
捕获所有异常的缺点是屏蔽可能有用的错误消息并忽略它,从而在您的应用程序中造成意外的副作用。