繁体   English   中英

在 C# 中,是否有任何我不应该使用的内置异常?

[英]In C#, are there any built-in exceptions I shouldn't use?

.NET 框架中是否有任何我不应该在自己的代码中抛出的异常,或者这是不好的做法? 我应该自己写吗?

您不应抛出由于用户错误而由CLR自动抛出的任何异常。 例如

  • StackOverflowException
  • 的NullReferenceException
  • AccessViolationException
  • 等......

这样做的原因是为调用API的人造成了混乱。 用户应该能够区分API主动抛出的异常和未主动抛出的异常(由CLR抛出)。

原因是主动抛出异常通常表示API中的已知状态。 如果我调用一个API并抛出一个ArgumentException,我有理由期望给定的对象处于良好的状态。 它认识到一种潜在的不良情况并积极地对其进行说明。 另一方面,如果它抛出NullRefrenceException,则表明API遇到未知错误,现在处于不可靠状态。

另一个较小的原因是,当用户代码抛出而不是CLR时,这些异常的行为会有所不同。 例如,如果用户代码抛出,则可能捕获StackOverflowException,但如果CLR抛出则不会。

编辑回应迈克尔的评论

您也不应该直接抛出Exception,ApplicationException或SystemException。 这些异常类型过于笼统,无法为调用API的代码提供有意义的信息。 如果是,您可以在message参数中添加非常具描述性的消息。 但是根据消息捕获异常并不是直接或可维护的。 根据类型捕获它会好得多。

关于这个主题的FxCop规则: http//msdn.microsoft.com/en-us/library/ms182338( VS.80) .aspx

框架中的大多数异常类都不是为了重用,因为它们通常用于表示某些特定于框架的错误。 @JaredPar提到的那些一样,框架使用它们来指示框架中的某些状态。

在框架中有几十个,也许几百个例外,因此IMO列出我们应该使用的那些更有用。 在我的头脑中,这些是我积极使用的:

对于用户代码中的其他错误条件,最佳做法是创建自己的异常类。

@Michael实际上有一种情况建议抛出NullReferenceException:如果扩展方法的第一个参数(“this”参数)为null。 您需要这样做才能使空变量按预期运行。

微软曾经告诉程序员不要直接从Exception继承,而是使用ApplicationException作为他们的基类。 不确定这个意见是否仍然适用,但......

如果已经存在一个预定义的异常,它涵盖了你的确切错误条件(比如“NullReferenceException”或“InvalidArgumentException”等) - 无论如何,抛出这些异常而不是在你自己的代码中重新发明它们。

没有人直接发布指向它的链接,所以这里是 MSDN 页面,其中包含异常注意事项的完整列表

https://learn.microsoft.com/en-us/do.net/standard/design-guidelines/using-standard-exception-types

在投掷方面,注意事项是......

  • 系统异常
  • 应用异常
  • 空引用异常
  • 访问冲突异常
  • 索引超出范围异常
  • 堆栈溢出异常
  • 内存不足异常
  • 异常
  • 执行引擎异常
  • SEH异常

它还有一个不要捕获的列表和关于你应该抛出哪些异常的建议

已经为您定义了几个例外。 在推出自己的例外之前,请务必尝试使用这些例外

在线例外设计指南中包含的原则意见(具体参见页)。

“框架设计指南:可重用.NET库的约定,惯用法和模式,第2版”一书中有更多细节和有关该主题的更多讨论。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM