.NET没有概念性(Fatal-)Error异常类型的设计原因?

马丁·巴

初步说明:

这个问题不是要在.NET上猛烈抨击,也不是要在发生“致命异常”之类的事情时展开一场讨论之战-Java的设计师清楚地认为存在,.NET设计师要么以为,否则就不知道。否则,或者可能有另一个(技术上的)原因使异常层次结构保持现状。

我最感兴趣的是任何MS设计师是否都有设计文档或声明,为什么.NET层次结构就是今天的样子。大胆的猜测和猜测将得出错误的答案。内在的争论/示例为什么没有这样的(可分类的)致命异常,当然可以做出有效的答案,尽管我一定不同意它们。但是,相对于评论,我保证不会与任何有粘性的答案争论;-)另一类答案可以表明Java的Error类型分类是一个坏主意/在Java中实际上不起作用,从而隐含地说明了.NET的原因。不需要它 :-)


在努力成为经验丰富的C#程序员的过程中,我注意到.NET异常层次结构中一些我认为很奇怪的东西(*)

所有抛出类型的基类Exception嗯,基本上无论如何)。

具体而言,许多异常直接来自于异常,Exception并且进一步分类SystemException->等似乎 毫无意义 ,有些武断。

举个例子,对我来说尤其奇怪的SEHExceptionis-a ExternalExpectionis-aSystemException确实看起来更像是一种崩溃和烧伤的错误。

虽然在Java方面没有过分的经验,但我发现Java在wrt方面与众不同。Error类型与“正常” Exception,使有很大的意义。当然可以争论细节,但是.NET/ C#甚至不尝试这种方法似乎很奇怪。

C#知名度的Eric Lippert很好地论述了我最同意的异常分类方法,这使我更加想知道为什么.NET甚至没有尝试为“致命异常”提供存储桶。


我基本上用“致命异常”来暗示利珀特先生描述的相同概念:

致命异常不是您的错,您无法阻止它们,也无法明智地清除它们。...

注意:最重要的是,它们很可能而且特别不是您调用的引发异常的操作的错误。

...几乎总是会发生这种情况,因为该过程已深陷疾病,并且即将摆脱痛苦。内存不足,线程中止等等。捕获这些绝对没有意义,因为您微不足道的用户代码无法执行任何操作来解决此问题。只是让您的“最终”障碍运行起来,并希望最好。(或者,如果您真的很担心,请快速失败,不要让finally块运行;这时,它们可能会使情况变得更糟。但这是另一天的话题。)

我将注意到,从技术上讲,某些致命异常与其他任何异常一样完全可以您应该能够在适当的时候捕获它-只是对于99%的代码根本不适合处理这些。

以Lipperts先生为例:假设我调用一个函数来打开可能引发各种异常的文件。如果发现其中任何一个,我要做的就是报告打开文件失败的原因X,并继续进行适当的操作。但是,如果打开文件引发了ThreadAbortedException,则报告任何内容都没有意义,因为文件打开操作没有失败,但是某些代码中止了当前线程,并与假定的FileNotFoundException不会同时处理该线程。在绝大多数情况下都是有道理的。


评论者似乎认为,只有捕获站点才能真正判断某些东西是否“致命”,并且没有适当的事先分类,但是我强烈怀疑有一个很好的例外列表,其中99%的用户代码从不希望捕获

采取StackOverflowException(而且我敢肯定还有更多)这只是“常规”的SystemException ,它被认为是致命的

在.NET Framework 1.0和1.1中,您可以捕获StackOverflowException对象(例如,从无限制的递归中恢复)。从.NET Framework 2.0开始,您无法使用try / catch块捕获StackOverflowException对象,并且默认情况下终止了相应的进程。

请注意,我认为一个致命异常,必须立即终止(相反)的应用程序。我要问的是,当设计人员明确地认为某些异常比其他异常更致命时,.NET框架为什么不尝试在异常的层次结构中表示“致命性”。


(*)“考虑相当奇怪”实际上意味着我个人,在时间连续体的这一点上,发现完全被破坏的.NET异常层次结构

埃里克·利珀特(Eric Lippert)

首先让我说,对于StackOverflow来说,这不是一个特别好的问题。这不是有关实际代码的特定技术问题,而是寻求设计文档(一种非现场资源),或者寻求为何按原样设计特定类层次结构的理由。两者都不太适合SO。

也就是说,我可以在这里进行一些观察。

我认为所有参与此事的人都对SystemException的存在感到遗憾,这是一个合理的假设ApplicationException在当时,将异常分为两大类似乎是个好主意:由“系统”本身生成的异常,以及由系统用户创建的异常。但是实际上,这不是一个有用的区别,因为您对异常所做的事情就是捕获它们,并且您希望在什么情况下捕获(1)所有用户生成的异常或(2)所有系统生成的异常?没想到会出现任何情况。

这说明在特定情况下并不是设计上的失败-尽管可以肯定的是设计不是很好-而是在单继承OOP中,您只能在“继承枢轴”上获得一枪通常会被称为Microsoft,一个糟糕的决定可能会长期困扰您。

现在很容易地说,回顾过去,我们也许应该使用其他一些枢轴。您注意到在我的文章中我根据异常的捕获方式对异常进行了分类-致命异常没有被捕获,因为捕获异常对您没有好处,硬骨头异常没有被捕获,因为它们实际上是调试的辅助工具,令人烦恼的异常必须被捕获由于API设计不佳,必须捕获外部异常,因为它们表明世界与您所希望的有所不同。似乎有可能在此处进行更好的调整,其中异常类型指示它是否致命,并指示是否需要被抓或不被抓。当然,这不是唯一可能的枢纽,但似乎是可行的。可以设计一个静态分析器(在编译器或第三方工具中),以验证是否正确捕获了异常。

似乎特别合理,因为.NET中当然有一些例外,这些例外实际上是超级双重错误。您可以捕获堆栈溢出或线程中止,但是系统会积极地重新抛出它们。如果以某种方式捕获到元数据中,那将是很好的。

作为语言设计者,尽管我会进行进一步的回顾,但我要说的是,这里的根本问题是,如果不滥用异常机制,它本身就会过度工作

例如,为什么我们需要致命的异常才能成为异常如果确实是某些异常是致命的情况,并且确实是在某些罕见但关键的情况下,即使由于致命异常而导致程序关闭,您也需要运行代码,那么该情况可能会上升到您希望语言中的语法捕获这些语义的级别说一个try-fatality块,其中清除代码在致命错误的极不可能的情况下运行。也许这是一个好主意,也许不是,但是重点是关于在语言中添加功能来解决问题的想法 而不是将越来越多的语义叠加到一种机制上,该机制似乎并不理想地适合其所使用的所有用途。

例如,为什么根本没有“骨头”异常?实际上存在一些异常例外,例如“不允许将此引用为null,您可以虚拟”或“您试图在关闭文件后写入文件,您可以虚拟”,这是唯一的例外,因为它们是以下方面的缺点:第一种情况是类型系统,第二种情况是API设计。理想情况下,不会出现白痴,因为首先根本不可能用该语言来表示不良程序。可以将诸如代码契约之类的机制内置到该语言中,以帮助确保在编译时捕获“骨头”异常情况。再说一次,也许这是个好主意,也许不是,但是重点是有机会在语言设计级别解决此问题,

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

.NET没有概念性(Fatal-)Error异常类型的设计原因?

来自分类Dev

概念性Rails / Nginx

来自分类Dev

嵌套循环多维数组。概念性

来自分类Dev

这种元素异常没有明显的原因

来自分类Dev

数组背后的设计原因没有打印出可读的表示

来自分类Dev

使用Swing的Java聊天应用程序(概念性)

来自分类Dev

如何使用SQL汇总某些概念性类的值?

来自分类Dev

没有lpthread的Promise中出现未知异常的原因

来自分类Dev

有关版本控制的概念性问题

来自分类Dev

异常设计模式,用于描述性更强的异常

来自分类Dev

具有Java异常的Python等效原因

来自分类Dev

ASP.NET Core MVC-无效的操作异常没有Ienumerable <SelectListItem>类型的viewdata

来自分类Dev

SpringMVC:@Transactional原因:没有定义类型为[...]的合格bean

来自分类Dev

莫纳德人不是在本质上只是“概念性”糖吗?

来自分类Dev

类型“ class *”没有得到增强的JPA异常

来自分类Dev

pytest异常没有类型对象不可调用

来自分类Dev

Mybatis中没有类型处理程序异常

来自分类Dev

异常“没有类型为'IEnumerable <SelectListItem>的ViewData项” MVC

来自分类Dev

获取JDBC类型的没有方言映射的异常

来自分类Dev

未处理的异常:即使数据中没有整数,“ String”类型也不是“ int”类型的子类型

来自分类Dev

原因:没有为名称为“ success”的“ chain”类型定义结果类型

来自分类Dev

有关多维数组和指针的概念性问题

来自分类Dev

Java中有很多异常的不良设计吗?

来自分类Dev

是否有更好的方法仅捕获特定的异常原因?

来自分类Dev

具有派生类型的Protobuf-net StackOverflow异常

来自分类Dev

为什么Scala没有枚举类型,当前设计有什么好处?

来自分类Dev

设计具有类型和类型的项目,其中项目类型与组类型相关

来自分类Dev

带有文件类型异常的Diff命令

来自分类Dev

TclError没有原因

Related 相关文章

  1. 1

    .NET没有概念性(Fatal-)Error异常类型的设计原因?

  2. 2

    概念性Rails / Nginx

  3. 3

    嵌套循环多维数组。概念性

  4. 4

    这种元素异常没有明显的原因

  5. 5

    数组背后的设计原因没有打印出可读的表示

  6. 6

    使用Swing的Java聊天应用程序(概念性)

  7. 7

    如何使用SQL汇总某些概念性类的值?

  8. 8

    没有lpthread的Promise中出现未知异常的原因

  9. 9

    有关版本控制的概念性问题

  10. 10

    异常设计模式,用于描述性更强的异常

  11. 11

    具有Java异常的Python等效原因

  12. 12

    ASP.NET Core MVC-无效的操作异常没有Ienumerable <SelectListItem>类型的viewdata

  13. 13

    SpringMVC:@Transactional原因:没有定义类型为[...]的合格bean

  14. 14

    莫纳德人不是在本质上只是“概念性”糖吗?

  15. 15

    类型“ class *”没有得到增强的JPA异常

  16. 16

    pytest异常没有类型对象不可调用

  17. 17

    Mybatis中没有类型处理程序异常

  18. 18

    异常“没有类型为'IEnumerable <SelectListItem>的ViewData项” MVC

  19. 19

    获取JDBC类型的没有方言映射的异常

  20. 20

    未处理的异常:即使数据中没有整数,“ String”类型也不是“ int”类型的子类型

  21. 21

    原因:没有为名称为“ success”的“ chain”类型定义结果类型

  22. 22

    有关多维数组和指针的概念性问题

  23. 23

    Java中有很多异常的不良设计吗?

  24. 24

    是否有更好的方法仅捕获特定的异常原因?

  25. 25

    具有派生类型的Protobuf-net StackOverflow异常

  26. 26

    为什么Scala没有枚举类型,当前设计有什么好处?

  27. 27

    设计具有类型和类型的项目,其中项目类型与组类型相关

  28. 28

    带有文件类型异常的Diff命令

  29. 29

    TclError没有原因

热门标签

归档