当前位置:  开发笔记 > 编程语言 > 正文

为什么在.NET中没有检查异常?

如何解决《为什么在.NET中没有检查异常?》经验,为你挑选了5个好方法。

我知道谷歌搜索我可以找到一个合适的答案,但我更喜欢听你的个人(也许是技术)意见.
抛出异常时Java和C#之间差异的主要原因是什么?
在Java中,抛出异常的方法的签名必须使用"throws"关键字,而在C#中,如果可以抛出异常,则在编译时不知道.



1> Atif Aziz..:

在文章The Trouble with Checked Exceptions和Anders Hejlsberg(C#语言的设计者)自己的声音中,C#不支持检查异常有三个主要原因,因为它们在Java中被发现和验证:

对已检查的例外情况保持中立

"对于已检查的异常问题,C#基本上是无声的.一旦知道了更好的解决方案 - 相信我,我们会继续思考它 - 我们可以回去并实际放置一些东西."

使用Checked Exceptions进行版本控制

"在新版本中向throws子句添加新异常会破坏客户端代码.这就像在界面中添加方法一样.在发布一个接口之后,它是出于所有实际目的而不可变的......"

"人们认为关于例外的重要事情是如何处理它们,这很有趣.这不是关于例外的重要事情.在一个写得很好的应用程序中,我认为最终尝试捕获的比例为十比一.或者在C#中, using语句就像最后一样尝试."

Checked Exceptions的可伸缩性

"在小的,经过检查的例外中非常诱人......当您开始构建大型系统时,麻烦就开始了,您可以与四个或五个不同的子系统进行通信.每个子系统抛出四到十个异常.现在,每当你走上聚合的阶梯时,你就有了这个指数层次结构,在你必须处理的异常之下.你最终不得不宣布你可能抛出的40个例外.......它只是气球失控."

在他的文章中," 为什么C#没有异常规范?",Anson Horton(Visual C#项目经理)也列出了以下原因(有关每一点的详细信息,请参阅文章):

版本

生产力和代码质量

让类作者区分已检查未检查的异常是不切实际的

难以确定接口的正确异常.

值得注意的是,C#确实支持通过标记给定方法抛出异常的文档,编译器甚至会麻烦地验证引用的异常类型确实存在.但是,在呼叫站点或方法的使用中没有进行检查.

您可能还想查看Exception Hunter,这是Red Gate Software的一个商业工具,它使用静态分析来确定和报告方法引发的异常,并且可能未被捕获:

Exception Hunter是一种新的分析工具,可以在您发布之前查找并报告您的函数可能会抛出的一组可能的异常.有了它,您可以轻松快速地找到未处理的异常,直到抛出异常的代码行.获得结果后,您可以在将应用程序发布到野外之前确定需要处理哪些异常(使用一些异常处理代码).

最后,Thinking in Java的作者Bruce Eckel发表了一篇名为" Java是否需要检查异常?",这也许值得一读,因为在C#中为什么没有检查异常的问题通常在与Java的比较中扎根.


有趣的是,根据我的经验,许多开发人员倾向于忽略"一旦知道更好的解决方案" - 部分.现在在2015年,距离该声明差不多12年后,我还没有看到任何"更好的解决方案"在C#或任何其他语言如Kotlin等(或者我是否想念它?我现在不再使用C#进行编程了.)只是在没有更好的解决方案的情况下删除已检查的异常会使思考更糟,恕我直言 在一些重构之后,我们在一个C#应用程序中度过了一段不愉快的时间,以验证在所有情况下是否都能正确处理异常,因为编译器无法判断.

2> noah..:

因为对检查异常的响应几乎总是如此:

try {
  // exception throwing code
} catch(Exception e) {
   // either
   log.error("Error fooing bar",e);
   // OR
   throw new RuntimeException(e);
}

如果您确实知道如果抛出特定异常就可以执行某些操作,那么您可以捕获它然后处理它,但除此之外,它只是安抚编译器的咒语.


@mcjabberz JDK过度使用它们.那是Java的错.
如果程序员很懒,那Java是怎么回事?如果程序员过度使用它们,那那就是糟糕的API设计,再次,那Java是怎么回事?在我的书中,向后弯曲语言来安抚懒惰或愚蠢从来都不是一个好主意.我认为,检查异常是一种有用的工具,仅此而已
但实际上,它不应该.很多例外都不是致命的.主要问题是Checked可能不应该是默认的异常类型,并且它们在Java中被过度使用.但Checked异常仍然有用.
如果我没有在代码中捕获异常,我希望C#创建警告。这将使生活变得更加轻松。

3> Derek Slager..:

C#的基本设计理念是,实际捕获异常很少有用,而在特殊情况下清理资源非常重要.我认为using(IDisposable模式)是检查异常的答案是公平的.有关详细信息,请参见[1].

    http://www.artima.com/intv/handcuffs.html



4> Constantin..:

在.NET设计时,Java已经检查了异常很长一段时间,Java开发人员最多只能查看此功能 争论的 有争议的.因此,.NET设计者选择不将其包含在C#语言中.



5> DrPizza..:

从根本上说,是否应该处理异常是调用者的属性,而不是函数的属性.

例如,在某些程序中,处理IOException没有任何价值(考虑临时命令行实用程序来执行数据处理;它们永远不会被"用户"使用,它们是专家们使用的专业工具).在某些程序中,在调用"接近"的位置处理IOException是有价值的(可能如果您获得配置文件的FNFE,您将退回到某些默认值,或者查看其他位置,或者其他某个位置性质).在其他程序中,您希望它在处理之前冒泡很长时间(例如,您可能希望它在中止到达UI之前中止,此时它应该警告用户出现了问题.

每种情况都取决于应用程序,而不是.然而,在检查过的例外情况下,正是图书馆做出决定.Java IO库决定它将使用已检查的异常(强烈鼓励处理呼叫的本地异常),而在某些程序中,更好的策略可能是非本地处理,或根本没有处理.

这显示了在实践中检查异常的真正缺陷,并且它比浅表(虽然也很重要)缺陷更为基础,因为太多人会编写愚蠢的异常处理程序,只是为了让编译器闭嘴.我描述的问题是一个问题,即使经验丰富,尽职尽责的开发人员正在编写程序.

推荐阅读
小白也坚强_177
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有