如何CIL'故障'条款从C#'抓'的条款有什么不同? [英] How are CIL 'fault' clauses different from 'catch' clauses in C#?

查看:176
本文介绍了如何CIL'故障'条款从C#'抓'的条款有什么不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

按照 CLI标准(分区IIA,第18章)和MSDN对于 System.Reflection.ExceptionHandlingClauseOptions 枚举,有四种不同类型的异常处理模块:




  • 条款:的赶指定类型的所有对象。

  • 过滤器条款:只有当过滤器成功进入处理程序。

  • 最后条款:。处理所有异常和正常退出

  • 故障条款:处理所有异常,但不正常的退出。



鉴于这些简单的解释(从CLI标准的引用,顺便说一句),这些都应该映射到C#如下:




  • — 赶上(FooException){...}

  • 过滤器—在C#中不存在(但在VB.NET为捕捉FooException当booleanExpression

  • 最后— 终于{...}

  • 故障— 赶上{...}



实验:



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

  //使用System.Linq的; 
//使用的System.Reflection;

静态布尔IsCatchWithoutTypeSpecificationEmittedAsFaultClause()
{

{
返回MethodBase
.GetCurrentMethod()
.GetMethodBody()
.ExceptionHandlingClauses
。任何(第=> clause.Flags == ExceptionHandlingClauseOptions.Fault);
}
捕捉//< - 这就是上面的代码检查
{
扔;
}
}

这方法的返回值。也就是说,赶上{...} 尚未发出的一个错误的条款。



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



问题:




  1. 如果赶上{...} 真的是一个catch子句,那么如何从catch子句不同故障的条款?

  2. 请问C#编译器不断输出故障的条款呢?


解决方案

有四种不同的异常处理模块:




  • 条款:捕捉指定类型的所有对象

  • 过滤器条款:输入仅当过滤器成功处理程序。

  • 最后条款:处理所有异常和正常退出

  • 故障条款:。处理所有异常,但不正常的退出



由于这些简单的解释(从CLI标准的引用,顺便说一句),这些都应该映射到C#如下:




  • &MDASH; 赶上(FooException){...}

  • 过滤器&MDASH;在C#中不存在(但在VB.NET为捕捉FooException当booleanExpression

  • 最后&MDASH; 终于{...}

  • 故障&MDASH; 赶上{...}




这是你在哪里错了最后一道防线。再次阅读说明。 故障最后实际上是相同的描述。它们之间的区别是,最后总是进入,而故障只有进入当控制离开尝试通过一个例外。请注意,这意味着块可能已经采取行动



如果你写在C#中:

  {试

}赶上(SpecificException前){
$ ... b $ b} {赶上

}

再有就是没办法,如果控制通过 SpecificException 离开尝试第三块将被输入。这就是为什么捕捉{} 不是故障


的映射

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

  • 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."

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

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

Experiment:

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;
    }
}

This method returns false. That is, catch { … } has not been emitted as a fault 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.

Questions:

  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 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."

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

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

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.

If you write this in C#:

try {
    ...
} catch (SpecificException ex) {
    ...
} 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'故障'条款从C#'抓'的条款有什么不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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