异常类:在C# (.Net)中何时派生自它?

4
我正在进行我的考试复习。
我遇到了Base Exception类的使用,并且在考试卷上也看到过。
我的问题是什么时候应该从Base Exception类派生?
我认为,如果您想要一个自定义类来抛出具有更有意义的信息的异常,那么您可以创建一个自定义异常类,其中包含与您的自定义类如何使用以及设计用于哪种情况的确切数据。
为什么我的自定义异常类不能从'ApplicationException'或'SecurityException'或基本'Exception'类派生?
我认为我应该从基本的Exception类而不是前两个派生。
我的第二个问题是,什么时候会从其他两个中派生?是否有任何明显的区别,可以清楚地说明您何时会从其中之一派生?假设没有我错过的其他人?
*小更新:*
这个问题几乎击中了钉子。
*应该使用哪个类生成特定于应用程序的异常?*
答案:ApplicationException类

1
关于你的“小更新”,MSDN文档明确表示不要ApplicationException派生或使用它。X 不要抛出或从ApplicationException派生。 - Doctor Jones
@Jones 医生 - 干杯,老兄。回顾这个问题已经过了这么长时间,我知道这句话如掌上明珠般易于记忆。 - IbrarMumtaz
4个回答

4
这些内容在《设计指南》文档中都有详细讨论,可参考该文档

2
非常有趣。我之前没有意识到ApplicationException在某种程度上已经被宣布过时了。 - BlueMonkMN
基本上...它非常明确地表示你不应该使用它!!! 对我来说已经足够好了 :) - IbrarMumtaz

3
在我们最近的项目中,我们使用了一个基本异常类。我们使用它来获得以下功能:
  • 所有异常都需要一个数字,因此在基类中定义了该属性
  • 所有异常消息需要以相同的方式进行格式化,包括数字、原因和类型。这个格式化消息是在基类中完成的。
我们的基本异常类派生自ApplicationException。这可能是一个错误,因为有很多关于继承深度过大的问题的讨论。然而,我们没有遇到任何问题。
考试的一个提示:非常仔细地阅读问题。祝你好运。

2
通常情况下,您需要从最接近您想引发的异常类型的Exception类派生。如果问题是由于传递了某些参数或参数导致的问题,请使用ArgumentException。如果需要进行一些自定义操作,请继承自ArgumentException。
在我的经验中,仅有两个原因使用基本Exception:1)当您需要完全不符合当前异常模型之一的自定义异常时;2)当方法理论上可能引发多个异常,但您已经捕获了最有可能引发的异常。
通常,我根本不会从异常中继承。仅设置Message属性通常就足够了。

谢谢回复。我会在阅读设计指南文档时记住这一点。 - IbrarMumtaz

0
理想情况下,异常应该分组成一个层次结构,以便如果代码想要以相同的方式处理多个异常,它们都将派生自一个共同的基类。如果基础可抛类型是接口而不是类,这样的理想可能会有所实现。然而,由于类的单继承限制严重限制了层次结构的实用性。
异常层次结构唯一有用的时候是当接口的实现或者一个被记录为抛出某些异常的类的新版本想要允许代码区分比那些异常报告的更多的不同条件时。在这种情况下,抛出不从记录中继承的异常将是一个破坏性的变化,因此必须抛出一个继承自最能描述先前未预期条件的记录异常的异常。这很丑陋,但异常处理机制确实没有提供更好的替代方案。非常不幸的是,像 IEnumerator.MoveNext() 这样的东西并没有被记录为抛出任何异常,这只意味着“对不起——系统没有着火或其他什么事情,我也不知道是否有人更改了集合,但我既不能前进到下一个项目,也不能真诚地说枚举已经完成”,但它们没有。

除了需要抛出与现有代码兼容的异常之外,将应用程序或库使用的异常派生自一个公共基类可能会很有帮助。不要使用 ApplicationException,而应该使用像 YourApplicationNameExceptionYourLibraryNameException 这样的名称——这些名称不太可能被其他内容派生。像 ApplicationException 这样的名称是不好的,因为执行 catch ApplicationException 的代码将得到不仅从该类型派生的异常,还包括任何其他库派生的异常。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接