C#中的异常处理是否与ECMA-335标准相矛盾?

Chr*_*ens 23 .net c# specifications exception-handling

我的理解是基于这篇很长但很棒的文章,该文章支持C#规范中列出的行为.

CLI标准(EMCA-335)显示如果没有合适的catch,运行时应立即终止..NET运行时不会这样做,而是倾向于倾向于C#规范(EMCA-334)的行为.

首先,我觉得奇怪的是语言规范似乎是定义框架行为.其次,他们似乎是矛盾的.

  • 它们是否相互矛盾,或者我是否得到了错误的文件含义?
  • 运行时是否必须以这种方式进行异常处理以符合标准?

作为一个可选的问题,哪一个是"正确的"问题,如果我要编写自己的CLI实现,我应该使用哪一个?请注意,EMCA-335(CLI)文档在两个月前更新,其中EMCA-334(C#)于2006年更新.


ECMA-335分区I第12.4.2.5节

  • 发生异常时,CLI将在阵列中搜索第一个受保护的块
    • 保护包含当前指令指针和区域的区域
    • 是一个catch处理程序块和
    • 谁的过滤器希望处理异常
  • 如果在当前方法中找不到匹配项,则搜索调用方法,依此类推.如果未找到匹配项,CLI将转储堆栈跟踪并中止该程序.

  • 如果找到匹配项,CLI会将堆栈移回到刚定位的点,但这次调用finally和fault处理程序.然后它启动相应的异常处理程序.

C#规范§15.9.5和§15.10(MSDN上的§8.9.5和§8.10)

它与CLI标准之间的主要区别在于,无论是否找到了catch块,应用程序都不会存在,但仍将展开堆栈,并处理最终的处理程序.

我建议阅读标准本身以获得更好的意义,因为下面是一个非常粗略的总结.它概述了如何使用每种可能的方案执行try语句.

  • 在引发异常的函数中:
    • 在每个try语句中查找匹配的catch子句
      • 执行catch语句(如果存在)
    • 如果存在,则执行finally块
  • 如果没有处理程序,则在调用函数中重复上述步骤
  • 如果异常处理终止当前线程中的所有函数成员调用,指示该线程没有该异常的处理程序,则该线程本身终止.这种终止的影响是实现定义的.

Han*_*ant 5

这里没有冲突。C#语言规范的措辞如下:

\n\n
\n

如果try语句没有catch子句或者没有catch子句匹配异常:
\n \xe2\x80\xa2 如果try语句有finally块,则执行finally块。
\n \xe2\x80\xa2 异常将传播到下一个封闭的 try 语句。

\n
\n\n

这里的第 2 条特别没有说明当没有下一个封闭的 try 语句时会发生什么。为此,请参阅 8.9.5 的末尾:

\n\n
\n

如果异常处理终止了当前线程中的所有函数成员调用,表明该线程没有异常处理程序,则该线程本身将终止。此类终止的影响是由实现定义的。

\n
\n\n

它当然是实现定义的。除了 Ecma 335 规范之外,异常处理策略是 Microsoft CLR 中的一个可配置项。由 ICLRPolicyManager::SetActionOnFailure() 控制。反过来,可以使用<legacyUnhandledExceptionPolicy>app.exe.config 文件元素在默认主机中进行配置。CLR 2.0 及更高版本的默认设置是立即终止程序。

\n\n

否则,这是相当低效的圣经解释学。对于 C# 程序员来说,这一切都不应该感到惊讶,特别是考虑到测试非常容易。

\n


Jon*_*nna 3

我认为这可能只是一个措辞模糊的问题。

如果在当前方法中未找到匹配项,则搜索调用方法,依此类推。如果未找到匹配项,CLI 将转储堆栈跟踪并中止程序。

好吧,在 C# 中确实如此。我们都知道,如果我们没有异常,catch那么异常就会导致我们的程序崩溃。

如果找到匹配项,CLI 会将堆栈返回到刚刚定位的点,但这次调用finally 和fault 处理程序。然后它启动相应的异常处理程序。

这也符合我们从 C# 中了解到的情况。如果有一些finally(我们看不到的fault)块需要处理,当我们从抛出异常到我们的块为止向上移动堆栈时catch,它们会被处理,但它会停在那里并且不再向上移动堆栈。

很大程度上取决于我们如何阅读我刚才引用的第二段摘录开头的“如果”。你读它是“如果……那么……否则就没有这样的事情”。它可以被理解为识别堆栈中将要走到的点的第一个摘录:如果有一个catch,那么它就会走到该点。如果没有捕获,那么它就会走到堆栈的最顶部,我们会得到一个转储并中止。finally 处理程序(和错误处理程序)仍然会被调用,但重点不在于匹配的 catch 处理程序。

你的阅读是最直白的,而我的则是稍微延伸了一些内容。然而,我的确实与同一标准中其他地方的描述相符finally,最接近