CIL'fault'子句如何与C#中的'catch'子句不同? [英] How are CIL 'fault' clauses different from 'catch' clauses in C#?

查看:158
本文介绍了CIL'fault'子句如何与C#中的'catch'子句不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 CLI标准 (分区IIA,第19章)以及用于 System.Reflection.ExceptionHandlingClauseOptions 枚举,有四种不同种类的异常处理程序块:

According to the CLI standard (Partition IIA, chapter 19) and the MSDN reference page for the System.Reflection.ExceptionHandlingClauseOptions enum, there are four different kinds of exception handler blocks:


  • catch 子句:抓住指定类型的所有对象。

  • strong>子句:只有当过滤器成功时才输入处理程序。

  • finally 子句:处理所有异常和正常退出。

  • 错误子句:处理所有异常但不正常退出。

  • catch clauses: "Catch all objects of the specified type."
  • filter clauses: "Enter handler only if filter succeeds."
  • finally clauses: "Handle all exceptions and normal exit."
  • fault clauses: "Handle all exceptions but not normal exit."

给出这些简要的解释(从CLI标准引用,btw。),这些应该映射到C #如下:

Given these brief explanations (cited from the CLI Standard, btw.), these should map to C# as follows:


  • catch catch(FooException){...}

  • 过滤器—在C#中不可用(但在VB.NET中为 Catch FooException当booleanExpression

  • finally finally {...}

  • 故障 catch {...}

  • catchcatch (FooException) { … }
  • filter — not available in C# (but in VB.NET as Catch FooException When booleanExpression)
  • finallyfinally { … }
  • faultcatch { … }

一个简单的实验表明,这个映射不是.NET C#编译器真正做的:

A simple experiment shows that this mapping is not what .NET's C# compiler really does:

// using System.Linq;
// using System.Reflection;

static bool IsCatchWithoutTypeSpecificationEmittedAsFaultClause()
{
    try
    {
        return MethodBase
               .GetCurrentMethod()
               .GetMethodBody()
               .ExceptionHandlingClauses
               .Any(clause => clause.Flags == ExceptionHandlingClauseOptions.Fault);
    }
    catch // <-- this is what the above code is inspecting
    {
        throw;
    }
}

此方法返回 false 。也就是说, catch {...} 没有作为故障条款发布。

This method returns false. That is, catch { … } has not been emitted as a fault clause.

类似的实验表明,事实上,发出一个catch子句( clause.Flags == ExceptionHandlingClauseOptions.Clause ),即使没有指定例外类型。

A similar experiment shows that in fact, a catch clause was emitted (clause.Flags == ExceptionHandlingClauseOptions.Clause), even though no exception type has been specified.


  1. 如果 catch {...} 真的是catch子句,那么fault子句与catch子句的区别呢?

  2. C#编译器是否根本输出了错误子句?

  1. If catch { … } really is a catch clause, then how are fault clauses different from catch clauses?
  2. Does the C# compiler ever output fault clauses at all?


推荐答案


有四种不同种类的异常处理程序块:

there are four different kinds of exception handler blocks:


  • catch 子句:抓住指定类型的所有对象。

  • / strong>子句:只有当过滤器成功时才输入处理程序。

  • finally 子句:处理所有异常正常退出。


  • catch clauses: "Catch all objects of the specified type."
  • filter clauses: "Enter handler only if filter succeeds."
  • finally clauses: "Handle all exceptions and normal exit."
  • fault clauses: "Handle all exceptions but not normal exit."

鉴于这些简要的解释(从CLI标准引用,btw。),这些应该映射到C#,如下所示:

Given these brief explanations (cited from the CLI Standard, btw.), these should map to C# as follows:


  • 抓住 catch(FooException){...}

  • 过滤器—在C#中不可用(但在VB.NET中为 Catch FooException当booleanExpression

  • finally finally {...}

  • 故障 catch {...}

  • catchcatch (FooException) { … }
  • filter — not available in C# (but in VB.NET as Catch FooException When booleanExpression)
  • finallyfinally { … }
  • faultcatch { … }

最后一行你错了。再次阅读说明。 fault finally 的描述实际上是相同的。它们之间的区别在于,始终输入 finally ,而只有在控件留下$ $ c $时才输入 fault c>尝试通过一个例外。请注意,这意味着 catch 块可能已经被执行。

It's that last line where you went wrong. Read the descriptions again. fault and finally are described practically identically. The difference between them is that finally is always entered, whereas fault is only entered if control leaves the try via an exception. Note that this means that a catch block may have already acted.

如果你在C#中写这个: p>

If you write this in C#:

try {
    ...
} catch (SpecificException ex) {
    ...
} catch {
    ...
}

然后有如果控件通过 SpecificException 尝试,则不会输入第三个块。这就是为什么 catch {} 不是故障的映射

Then there is no way that the third block will be entered if control leaves the try via a SpecificException. That's why catch {} isn't a mapping for fault.

这篇关于CIL'fault'子句如何与C#中的'catch'子句不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆