如果我需要从我的应用程序中抛出异常,我可以使用哪些内置的.NET异常类?他们都是公平的游戏吗?我什么时候应该自己推出?
请参阅创建和抛出异常.
在抛出内置异常时,它说:
不要故意从您自己的源代码中抛出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存在争议(即许多开发人员抛出此异常).
对主题System.Exception
和System.ApplicationException
:后者本来是用作基类所有自定义异常.但是,从一开始就没有一贯强制执行.因此,是否应该使用此类而不是将其System.Exception
用作所有异常的基类存在争议.
无论你决定哪种方式,都不要直接抛出这两个类的实例.实际上很遗憾他们不是abstact
.对于它的价值,总是尝试使用最具体的异常.如果没有人满足您的要求,请随意创建自己的要求.但是,在这种情况下,请确保您的例外优于现有例外.特别是,它应该完美地传达其含义,并提供以有意义的方式处理这种情况所需的所有信息.
避免创建不执行任何有意义的存根异常.同样,避免创建巨大的异常类层次结构,它们很少有用(尽管我可以想象一下我会使用它们的情况......解析器就是其中之一).
我ArgumentException
经常使用(和它的"朋友").
NotSupportedException
并且NotImplementedException
也很常见.
我的建议是集中在两件事上:
情境
用户期望
换句话说,我会坐下来确定:
您想在什么情况下抛出异常。
在这些情况下,您的API用户会期望什么
#1的答案当然是针对特定应用的。对#2的答案是“他们已经熟悉的所有相似代码”。
由此产生的行为是:
在程序也出现在框架内部的情况下,例如参数为空,超出范围,无效,未实现或仅不支持方法,那么应该使用框架使用的相同例外。使用您的API的人们会期望他们的行为方式相同(因为这就是其他所有行为的方式),因此可以更好地使用“开始使用”的api。
对于框架中不存在的新场景,您应该继续并发明自己的异常类。我想说,您应该更喜欢Exception作为您的基类,除非它们是提供您所需服务的其他一些基本异常。一般来说,我认为“ ApplicationException”不会对您有太大帮助。当您开始定义自己的异常时,请记住以下几点:
一种。例外的主要目的是为了与人交流。他们传达有关不应该发生的事情的信息。他们应该提供足够的信息来确定问题的原因并找出解决方法。
b。内部一致性非常重要。在相似的情况下,使您的应用程序尽可能具有普遍性,将使您的API用户更加高效。
至于关于应该做什么和不应该做什么的严格规定,我不会担心这些东西。相反,我将只专注于识别方案,找到适合那些方案的现有异常,然后在不存在现有方案的情况下仔细定义自己的方案。