我可以从我的应用程序抛出哪些内置的.NETexception?
如果我需要从我的应用程序中抛出一个exception,我可以使用哪些内置的.NETexception类? 他们都是公平的游戏吗? 我应该何时得到我自己的?
请参阅创build和抛出exception 。
抛出内置的exception,它说:
不要从您自己的源代码中故意抛出System.Exception,System.SystemException,System.NullReferenceException或System.IndexOutOfRangeException。
和
不要抛出一般例外
如果在库或框架中引发常规exceptiontypes(例如Exception或SystemException),则会强制消费者捕获所有exception,包括他们不知道如何处理的未知exception。
相反,要么抛出一个已经存在于框架中的更多的派生types,要么创build自己派生自Exception的types。
这个博客条目也有一些有用的指导方针。
此外,FxCop代码分析定义了这里描述的“不要引发exception”的列表。 它build议:
以下exceptiontypes过于笼统,无法为用户提供足够的信息:
- System.Exception的
- System.ApplicationException
- System.SystemException
以下exceptiontypes是保留的,应该仅由公共语言运行库引发:
- System.ExecutionEngineException
- System.IndexOutOfRangeException
- System.NullReferenceException
- 为System.OutOfMemoryException
所以从理论上讲,您可以提出任何其他框架exceptiontypes,只要您清楚地了解Microsoft描述的exception的意图(请参阅MSDN文档)。
请注意,这些是“指导原则”,正如其他一些人所说,围绕System.IndexOutOfRangeException存在争议(即许多开发者抛出这个exception)。
关于System.Exception
和System.ApplicationException
:后者被用作所有自定义exception的基类。 但是,这从一开始就没有得到一贯的执行。 因此,这个类是否应该被使用而不是使用System.Exception
作为所有exception的基类是有争议的。
无论您决定如何,都不要直接抛出这两个类的实例。 他们不是abstact
的,实际上是可惜的。 对于什么是值得的,总是尽量使用最具体的例外。 如果没有满足您的要求,请随时创build自己的。 但是,在这种情况下,请确保您的例外与现有例外相比具有优势。 特别是要把它的意思完美地expression出来,提供处理这个情况所需要的全部信息。
避免创build没有任何意义的存根exception。 同样,避免创build巨大的exception类层次结构,它们很less有用(尽pipe我可以想象一个或两个使用它们的情况…parsing器就是其中之一)。
我经常使用ArgumentException
(及其“朋友”)。
NotSupportedException
和NotImplementedException
也是常见的。
我的build议是关注两件事情:
- scheme
- 用户的期望
换句话说,我会坐下来确定:
- 在什么情况下,你想抛出exception。
- 在这些情况下,API的用户期望什么
#1的答案当然是应用程序特定的。 #2的答案是“他们已经熟悉的类似代码”。
出来的行为是:
-
在您的程序中出现的也出现在框架内部的情况下,例如参数为null,超出范围,无效,方法没有实现,或者只是不受支持,那么您应该使用框架使用的相同例外。 使用API的人会期望他们的行为(因为这就是其他所有行为),所以能够更好地使用你的api。
- 对于框架中不存在的新场景,您应该继续并创build您自己的exception类。 我会说,你应该更喜欢exception作为你的基类,除非他们是一些其他的基本例外,提供您所需要的服务。 一般来说,我不认为像“ApplicationException”这样的东西会帮助你很多。 当你开始定义你自己的例外时,你应该记住一些事情:
一个。 例外的主要目的是为了人际沟通。 他们传达有关不应该发生的事情的信息。 他们应该提供足够的信息来确定问题的原因并找出解决的办法。
湾 内部一致性是非常重要的。 在类似情况下让您的应用程序尽可能普遍地运行,将使您的API用户更有效率。
只要有关于你应该做什么和不应该做什么的硬性规定,我不会担心这些。 相反,我只是专注于识别场景,find适合这些场景的现有exception,然后仔细地确定自己的场景,如果现有场景不存在的话。
你可以创build和抛出几乎任何一个,但你通常不应该。 作为一个例子,各种参数validationexception(ArgumentException,ArgumentNullException,ArgumentOutOfRangeException等)适用于应用程序代码,但AccessViolationException不适用。 ApplicationException作为您可能需要的任何自定义exception类的适当基类提供。
看到这个MSDN文章的最佳做法列表 – 它是指处理exception,但也包含创build它们的好build议…