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

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

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

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

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

 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 } 

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

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

我推荐一些链接:

  • C#中的exception处理
  • 试着抓
  • 例外和exception处理

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

 try { // Some Code } catch { } 

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

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

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

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

请有一个公共exception处理程序来处理所有未处理的exception。

HTH。

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

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

例如,检查File.Open()文档中的Exceptions段落。

使用自己的方法时,应该了解方法可能引发的exception。

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

在我看来,只有在你有充分理由抓住它们的情况下才能捕获exception。 这通常意味着不需要以通用方式捕获和处理它们。 记录exception(exception处理程序中的一个非常常见的活动)应该只发生在调用堆栈的底部或者不重新抛出(可能包装的)exception时,这种情况应该很少见。 如果您想要在exception发生时调用堆栈中的每一帧都执行某些操作,请查看面向方面编程(AOP)技术。

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

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

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

您应该捕获那些可以制定合理策略来处理问题的例外情况。 如果没有合理的替代方案,那么抓住exception是没有意义的(稍后再尝试,使用不同的技术/技术来实现相同的总体目标,通知用户目前无法实现目标以及他们可以采取哪些措施来纠正这种情况 ) 。

exception(原谅):值得在顶层使用某些东西(例如Application.ThreadException或AppDOmain.UnhandledException)来尝试记录那些你没有处理过的exception。 如果记录失败,无论如何你都注定要失败。

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

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

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

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