我可以从应用程序中抛出哪些内置的.NET异常?


Answers:


50

请参阅创建和引发异常

关于引发内置异常,它说:

不要故意从您自己的源代码中抛出System.Exception,System.SystemException,System.NullReferenceException或System.IndexOutOfRangeException。

不要抛出一般异常

如果在库或框架中抛出常规异常类型,例如Exception或SystemException,它将强制使用者捕获所有异常,包括他们不知道如何处理的未知异常。

相反,要么抛出框架中已经存在的更多派生类型,要么创建自己的从Exception派生的类型。”

博客条目也有一些有用的准则。

同样,FxCop代码分析定义了“不引发异常”的列表,如此处所述。建议:

以下异常类型太笼统,无法为用户提供足够的信息:

  • System.Exception
  • System.ApplicationException
  • System.SystemException

保留了以下异常类型,并且仅应由公共语言运行时抛出:

  • System.ExecutionEngineException
  • System.IndexOutOfRangeException
  • System.NullReferenceException
  • System.OutOfMemoryException

因此,从理论上讲,您可以引发任何其他框架异常类型,只要您清楚地了解Microsoft所描述的异常意图(请参阅MSDN文档)。

注意,这些是“准则”,正如其他人所说的那样,围绕System.IndexOutOfRangeException存在争论(即,许多开发人员都抛出此异常)。


2
为什么不IndexOutOfRandeException?当您有一个索引访问器(this [int index])并且提供的值超出了您所拥有的项目范围时,会发生什么?
Sekhat

1
我会排除:System.IndexOutOfRangeException,您有足够的理由自己扔一个。
嬉皮

1
重新IndexOutOfRangeException,这也是我的一个问题。文本来自链接的文章。
灰烬

1
如果适用,我会抛出IndexOutOfRangeException。似乎与ArgumentException,ArgumentNullException等位于同一个组中,我看不出不使用其中之一的原因。
OregonGhost

6
我认为他们希望您使用System.ArgumentOutOfRangeException而不是System.IndexOutOfRangeException。
JKor 2012年

9

关于System.Exceptionand的主题System.ApplicationException:后者旨在用作所有自定义异常的基类。但是,这从一开始就没有得到一致的实施。因此,是否应使用此类而不是将System.Exception所有异常用作基类存在争议。

无论您以哪种方式决定, 不要直接抛出这两个类的实例。遗憾的是他们没有abstact。出于价值考虑,请始终尝试使用最具体的异常。如果没有满足您要求的文件,请随时创建自己的文件。但是,在这种情况下,请确保您的例外优于现有例外。特别是,它应该完美地传达其含义,并以有意义的方式提供处理这种情况所需的所有信息。

避免创建没有任何意义的存根异常。同样,避免创建巨大的异常类层次结构,它们很少有用(尽管我可以想象会用到它们的一两种情况……解析器就是其中之一)。



5

我的建议是集中在两件事上:

  1. 情境
  2. 用户期望

换句话说,我会坐下来确定:

  1. 您想在什么情况下抛出异常。
  2. 在这些情况下,您的API用户会期望什么

当然,#1的答案取决于应用程序。对#2的答案是“他们已经熟悉的任何相似代码”。

由此产生的行为是:

  1. 在程序也出现在框架内部的情况下,例如参数为null,超出范围,无效,未实现或仅不支持方法,那么应该使用框架使用的相同例外。使用您的API的人们会期望他们的行为方式相同(因为这就是其他所有行为的方式),因此能够更好地使用“开始使用”的api。

    1. 对于框架中不存在的新方案,您应该继续并发明自己的异常类。我想说,您应该更喜欢Exception作为您的基类,除非它们是提供您所需服务的其他一些基本异常。一般来说,我认为“ ApplicationException”不会对您有太大帮助。当您开始定义自己的异常时,请记住以下几点:

    一种。例外的主要目的是为了与人交流。他们传达有关不应该发生的事情的信息。他们应该提供足够的信息来确定问题的原因并找出解决方法。

    b。内部一致性非常重要。在相似的情况下使您的应用程序尽可能具有通用性,将使您的API用户更加高效。

至于关于应该做什么和不应该做什么的严格规定,我不会担心这些东西。相反,我将只专注于识别方案,找到适合这些方案的现有异常,然后在不存在现有异常的情况下仔细定义自己的方案。


1

您几乎可以创建并抛出它们中的任何一个,但通常不应该这样做。例如,各种参数验证异常(ArgumentException,ArgumentNullException,ArgumentOutOfRangeException等)都适合在应用程序代码中使用,但AccessViolationException不适合。ApplicationException作为您可能需要的任何自定义异常类的合适基类提供。

请参阅此MSDN文章以获取最佳实践列表-它指的是处理异常,但也包含有关创建异常的好的建议...


3
ApplicationException不再用作自定义异常的基类。曾经是这种情况,但是Microsoft知道它没有用。使用Exception为基准,为自己的异常。
约翰·桑德斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.