为什么 C# 中不包含 Java“抛出”子句(在方法声明中)?
5 回答
Anders Hejlsberg(首席 C# 架构师)在这次采访中解释了这一点:
(除了帕特里克有些明确的答案。)
Java 中的检查异常是一个非常有争议的问题。我曾经很喜欢它们,在编写 C# 时非常想念它们。感觉就像我在没有安全带的情况下开车。现在,它们惹恼了我……因为虽然它们在理论上听起来是个好主意,但它们确实给我带来了很多悲伤,但没有提供太多切实的好处。我不记得曾经在 C# 代码中遇到过检查异常可以拯救我的错误。这并不是说它不会发生,但它没有发生在我身上。
令人讨厌的是,在某些方面它仍然感觉 C# 过于松懈——但 Java 的方法并不完全正确。好像有更好的解决方案等待被发现,Java 的尝试是一个很好的实验,但它并没有完全奏效。
我认为检查异常作为一种语言特性,暴露了微软和 Sun 之间的一些文化差异。
在大多数情况下,微软是一家客户公司。他们制作的大多数软件,以及他们的开发堆栈的目标,都是客户端软件。
是的,是的,我知道微软生产服务器软件。然而,就收入而言,Office 和 Windows 比 Windows Server 和 Exchange 大得多。
我认为可以公平地说大多数用 .NET 编写的软件(使用 VB 6 更是如此)是客户端软件。当然,其中很大一部分是运行在 Web 服务器上的 Web 软件,但其中大部分实际上是……“客户端类型的 Web 应用程序”。我想说大多数网络应用程序更像“Word”,然后它们就像 Exchange。
是的,我知道有 WCF 和 SOAP 服务以及类似的东西,但这些通常只是“客户端”类型的东西的“中间件”。
另一方面,Sun 主要是一家服务器公司。他们的软件在用户界面方面并不是最好的(这在 Unix 上并不是一个小问题......只是 Solaris.. Mac OS X 基于 unix,它有一个惊人的用户界面,两者之间的区别是 Sun 真的不像 Apple 那样关心 UI)。他们甚至出售瘦客户端,试图将所有内容推送到服务器上。
所以......无论如何......微软主要是客户公司,而Sun主要是服务器公司。
当您编写服务器软件时,可靠性是一件大事。它超大。如果电子邮件服务器崩溃,人们就收不到电子邮件,业务就会陷入停顿。因此,确保服务器能够智能地处理可能发生的大多数错误是销售电子邮件服务器的重要组成部分。
带客户端软件。可靠性很重要,但远没有服务器软件那么重要。只要大多数主线场景有效,人们就会很高兴。在许多情况下,可以忽略或一般处理疯狂的边缘场景。
超级可靠的一个关键是确保您处理所有可能发生的边缘情况。如果我们无法打开数据库文件,因为它被另一个进程锁定,或者我们没有读取它的权限,会发生什么?如果内存或磁盘空间不足怎么办?如果在运行此程序时断电会怎样?
对于非常高的可靠性要求,检查异常可能会有所帮助。如果有一个你没有预料到的场景,并且你对你的业务很重要,你可以预料到一切,那么让编译器告诉你......“嘿,你没有处理 RocketFuelExhaustedException”会很有帮助。
因此,我认为受检异常源于 Sun 作为服务器供应商的观点。
对于微软来说,作为一家向客户端软件开发人员销售开发工具的客户公司,检查异常当然是非常恼人的事情,会妨碍实际工作的完成。
无论如何,那是我的 0.02 美元...
主要原因是 C# 设计者决定不使用“检查异常”。这意味着开发人员不必在 try-catch 块中包含异常抛出子句。人们认为这仅对小规模应用程序有帮助,而对更大的项目没有真正的好处。此外,检查异常实际上被开发人员滥用,他们经常使用空的 catch 块。由于没有检查异常,因此没有理由声明可以引发哪些异常的方法。
“检查异常”的使用与否是一个有争议的话题,但大多数人似乎都同意没有必要使用它们。Spring 是 Java 中一个突出的框架,它将检查的异常转换为运行时异常。
异常显然是“异常”事件。在 .net 的范例中,永远不应该发生异常(这就是为什么你有像TryParse
, ... 这样的方法),所以被迫处理无论如何都不应该发生的事件是没有意义的。