【发布时间】:2012-08-16 13:13:32
【问题描述】:
根据CLI standard(Partition IIA,第 19 章)和 System.Reflection.ExceptionHandlingClauseOptions enum 的 MSDN 参考页,有四种不同的异常处理程序块:
- catch 子句:“捕获指定类型的所有对象。”
- filter 子句:“只有在过滤成功时才输入处理程序。”
- finally 子句:“处理所有异常并正常退出。”
- fault 子句:“处理所有异常但不是正常退出。”
鉴于这些简短的解释(引自 CLI 标准,顺便说一句。),这些应该映射到 C#,如下所示:
-
赶上 —
catch (FooException) { … } -
filter — 在 C# 中不可用(但在 VB.NET 中为
Catch FooException When booleanExpression) -
终于——
finally { … } -
故障 —
catch { … }
实验:
一个简单的实验表明,这个映射并不是 .NET 的 C# 编译器真正做的:
// 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 { … } 没有作为错误子句发出。
一个类似的实验表明,实际上发出了一个 catch 子句 (clause.Flags == ExceptionHandlingClauseOptions.Clause),即使没有指定异常类型。
问题:
- 如果
catch { … }真的是一个catch子句,那么fault子句和catch子句有什么不同? - C# 编译器是否曾经输出过错误子句?
【问题讨论】:
-
我不同意你的映射。
fault与finally类似,但只有当控件通过异常离开try块时才输入它。它不像catch {},因为只有在 no othercatch上面的块被输入时才会被输入。 -
你可能有一个观点。我没有想到那个细节,也许是因为我只考虑使用单个处理程序的 try 块,您提到的差异实际上无法观察到。
-
美丽的问题。正是我想要的。
标签: c# exception-handling system.reflection