.NET中有什么ApplicationException?


172

要抛出异常,我通常使用内置的异常类,例如ArgumentNullExceptionNotSupportedException。但是,有时我需要使用自定义异常,在这种情况下,我会写:

class SlippedOnABananaException : Exception { }
class ChokedOnAnAppleException : Exception { }

等等。然后我将它们扔到我的代码中。但是今天我遇到了ApplicationException全班学生-我应该改用它吗?这是为了什么?

拥有许多名称完全不同的有效相同的Exception类似乎没有效率(我通常不需要任何单独的功能)。但是我不喜欢捕获泛型ApplicationException并且必须使用额外的代码来确定错误是什么的想法。

ApplicationException我的代码应该放在哪里?


35
很好的问题,对于巧妙命名的示例异常也为+1
科迪·格雷

Answers:


100

根据msdn中的评论

用户应用程序(而不是公共语言运行时)会引发从ApplicationException类派生的自定义异常。ApplicationException类区分应用程序定义的异常和系统定义的异常。

如果要设计需要创建自己的异常的应用程序,建议您从Exception类派生自定义异常。最初认为自定义异常应该从ApplicationException类派生。然而,在实践中还没有发现这会带来重大价值。有关更多信息,请参见处理异常的最佳实践。

推导他们Exception。而且,只要有必要,我也不会为您的案例创建新的例外情况。如果遇到框架中已经存在异常的情况,请使用该异常,否则请自行滚动。


9
因此,这似乎ApplicationException没有用,仅仅是因为向后兼容吗?
Beatles1692 2015年

至少为4.7.2的新MSDN文档缺少此注释。谢谢你的qutoe:D
亚历克斯

147

简短的答案是:无处可去。

这是过去的遗物,Microsoft打算让开发人员从ApplicationException继承其所有自定义异常。此后不久,他们改变了主意,并建议自定义异常应从基类Exception派生。请参阅MSDN上处理异常的最佳实践

引起这种情况的最广泛的原因之一来自Jeffery Richter在《框架设计指南》中的摘录:

System.ApplicationException是一个类,不应属于.NET Framework。最初的想法是,从SystemException派生的类将指示从CLR(或系统)本身抛出的异常,而非CLR异常将从ApplicationException派生。但是,许多异常类没有遵循这种模式。例如,TargetInvocationException(由CLR引发)是从ApplicationException派生的。因此,ApplicationException类失去了所有含义。从该基类派生的原因是允许调用堆栈上方的某些代码捕获该基类。不再可能捕获所有应用程序异常。

所以你有它。执行摘要是ApplicationException不会有害,只是没有用


2
有人知道为什么吗?看起来很有意义,这样您就可以显示App异常,但不能显示“程序员搞砸了”异常。
乔什·科德洛夫

9
顺便说一句,从这种解释看来,这本身并不是一个坏的设计,但是MSFT搞砸了实现。其他人也有类似的读法吗?
乔什·科德洛夫

8
@JoshKodroff:我认为问题在于,如果应用程序Whizbang决定要使其所有异常都位于某个通用层次结构下,那么使用ApplicationException该目的实际上比使用自定义WhizbangException基类没有任何优势。.net异常体系中更严重的问题不是ApplicationException,而是由于无法将异常分为可能与应用程序致命,可能与线程致命和本地问题相关的类别,以及无法将异常分离有意义的“复合”异常。
2012年

@JoshKodroff:在正确设计的异常框架中,恕我直言,如果finally在另一个异常挂起的同时在块catch中引发异常,则如果它们与任何嵌套的异常匹配,则应触发调用堆栈更远的块,但将其他异常保留为挂起,以便退出一个catch块将前进到catchtry一块中的另一个块(如果合适的话),并且退出finally任何有未决异常的块将跳转到下一个外部catchfinally
超级猫

2
@JoshKodroff还有另一件事令我惊讶的是没有得到更多的关注。真正的“应用程序”是什么?第三方呢?由于这些不是.Net框架的一部分,因此应按照原始准则从ApplicationException继承。现在,当您在应用程序中使用该库并创建自己的ApplicationExceptions时,您将无法再基于该库从库的异常中识别出自己的异常。所以这没用。相反,每个组件都应仅定义其自己的异常基本类型,如supercat所述。
Oskar Berggren

22

在最初的设计中,在.NET 1.0中,计划框架本身将抛出SystemException并派生。而用户应用程序-将抛出ApplicationException并派生。

但是后来,在.NET 2.0中,它被删除了。

因此衍生自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.