为什么 .NET 中未签入异常?
我知道谷歌搜索我可以找到一个合适的答案,但我更喜欢听你的个人(也许是技术)意见。
Java和C#在抛出异常方面存在差异的主要原因是什么?
在Java中,引发异常的方法的签名必须使用“throws”关键字,而在C#中,您不知道在编译时是否可以引发异常。
我知道谷歌搜索我可以找到一个合适的答案,但我更喜欢听你的个人(也许是技术)意见。
Java和C#在抛出异常方面存在差异的主要原因是什么?
在Java中,引发异常的方法的签名必须使用“throws”关键字,而在C#中,您不知道在编译时是否可以引发异常。
在文章 The Problem with Checked Exceptions 和 Anders Hejlsberg(C# 语言的设计师)自己的声音中,C# 不支持已检查异常有三个主要原因,因为它们是在 Java 中发现和验证的:
对已检查的异常保持中立
“C# 在已检查的异常问题上基本上是无提示的。一旦知道了更好的解决方案——相信我,我们将继续考虑它——我们就可以回去,把一些东西放到位。
具有已检查例外的版本控制
“在新版本中向 throws 子句添加新异常会中断客户端代码。这就像向接口添加方法一样。发布接口后,它对于所有实际目的都是不可变的,...”
“有趣的是,人们认为异常的重要之处在于处理它们。这不是关于例外的重要事情。在我看来,在一个写得很好的应用程序中,有一个十比一的比例,即尝试最终尝试捕获。或者在C#中,
使用
语句,这就像尝试最后一样。
已检查异常的可伸缩性
“在小的,检查的例外是非常诱人的...当你开始构建大型系统时,麻烦就开始了,你正在与四五个不同的子系统交谈。每个子系统会引发四到十个异常。现在,每次你走上聚合的阶梯时,你都有这个指数级的层次结构,你必须处理异常。您最终必须声明40个可能引发的异常。...它只是失控了。
在他的文章“为什么 C# 没有异常规范?”中,Anson Horton(Visual C# 项目经理)还列出了以下原因(有关每个要点的详细信息,请参阅文章):
有趣的是,C#仍然支持通过<exception>
标记由给定方法引发的异常的文档,编译器甚至会费力地验证引用的异常类型确实存在。但是,在调用站点上没有进行检查或该方法的使用情况。
您可能还需要查看异常猎人,这是Red Gate Software的商业工具,它使用静态分析来确定和报告由方法引发的异常,并且可能未被捕获:
异常猎人是一种新的分析工具,可以在您发货之前查找并报告您的函数可能引发的一组可能的异常。有了它,您可以轻松快速地找到未处理的异常,直到引发异常的代码行。获得结果后,您可以决定在将应用程序发布到野外之前需要处理哪些异常(使用一些异常处理代码)。
最后,《Thinking in Java》一书的作者 Bruce Eckel 有一篇文章,名为“Java 需要检查异常吗?”,这篇文章可能也值得一读,因为为什么 C# 中没有检查的异常的问题通常在与 Java 的比较中扎根。
因为对已检查异常的响应几乎总是:
try {
// exception throwing code
} catch(Exception e) {
// either
log.error("Error fooing bar",e);
// OR
throw new RuntimeException(e);
}
如果你真的知道在抛出一个特定的异常时你可以做些什么,那么你可以抓住它,然后处理它,但除此之外,它只是安抚编译器的咒语。