在一篇题为“更干净、更优雅、更难识别”的旧博客文章中,作者指出:
在 C++ 中,它并没有那么糟糕,因为C++ 异常仅在执行期间的特定点引发。在 C# 中,可以随时引发异常。
他到底是什么意思?
首先,我会毫不犹豫地指责 Raymond Chen 将任何事情与任何事情混为一谈。
我怀疑他的意思是在 C++ 中,只有在存在throw
语句的情况下才会抛出异常。只要您对代码和库函数进行了足够深入的研究,您就可以准确地确定可能从哪里引发异常。另一方面,在 C# 中,运行时环境随时可能抛出异常。例如,您可能会在尝试调用任何其他程序集中的任何函数时遇到安全异常。
也许换一种说法:
在 C++ 中可以编写提供 nothrow 保证的函数。
我不知道 C#,我很确定 Raymond Chen 知道,所以我接受他的说法,即“在 C# 中,可以随时引发异常”。因此,您不能在 C# 中编写提供 nothrow 保证的函数。
在 C++ 中,nothrow 函数是提供其他异常保证的函数的一个非常重要的组件。为了做出强有力的保证(即实现事务),您通常需要诸如 nothrow 交换之类的东西,它执行多个语句而不会被异常中断。为了做一个基本的保证,你不需要清理资源,你可能还需要很短的 nothrow 代码段,其中你的对象的状态违反了它们的类不变量。
枚举 C++ 中所有可能引发异常的“特定点”可能很乏味,但实际上编写一段绝对不会的短代码并不难。如果你不能在 C# 中做到这一点,那将是一个重要的区别。
如果 Chen 关于 C# 的说法是错误的,那么他的意思可能并不重要。因为他错了。
在完整阅读这篇文章时,我注意到他主要是在谈论示例代码不正确(对实际代码有明显的影响)。因此,如果由于某些绝对不会抛出的 C# 代码的特殊情况而导致他的 C# 声明不正确,但此类 C# 代码从未出现在教程示例中,那么他仍然会对语言的教学方式有一个重要的观点——示例遗漏了使示例代码异常安全所需的基本内容可能是不好的示例,并且它们冒着教坏习惯的风险。并且与错误代码示例不同,学生(Chen 说)不能一眼看出该示例是坏的,因此可能没有意识到需要做更多的工作才能使它们“不坏”。
我认为他在谈论异步异常,在 C# 中可以在一个线程中引发,因为在另一个线程中发生了一些事情。(请注意,陈的博客条目中的一位评论者以相同的方式解释了他所写的内容,但不幸的是陈没有对此作出回应。)
参见,例如, http: //msdn.microsoft.com/en-us/library/system.threading.threadabortexception.aspx,其中一个线程调用Abort
代表另一个线程的对象的方法,导致另一个线程获得一个ThreadAbortException
.
他可能的意思是,在C++ 中,异常不是由框架引发的,而只是来自您的代码(或由将其代码视为“他们自己的代码”的人编写的外部代码)。在 C# 中,异常也可能发生在框架中。
然而,我不明白为什么作者似乎更喜欢只从您自己的代码中引发异常。