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

时间:2009-04-18 15:37:39

标签: c# .net exception

.NET Framework中是否定义了我不应该在自己的代码中引入的异常,或者这是不好的做法?我应该自己写吗?

6 个答案:

答案 0 :(得分:22)

您不应抛出由于用户错误而由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

答案 1 :(得分:9)

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

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

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

答案 2 :(得分:3)

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

答案 3 :(得分:2)

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

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

马克

答案 4 :(得分:0)

已经为您定义了几个例外。在推出自己的

之前,请务必尝试使用这些Exceptions

答案 5 :(得分:0)

在线Design Guidelines for Exceptions包含主要建议(具体参见this页面)。

本书"Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition"有更多详细信息和更多关于此主题的讨论。