根据CLI 标准(Partition IIA,第 19 章)和System.Reflection.ExceptionHandlingClauseOptions
enum的 MSDN 参考页,有四种不同类型的异常处理程序块:
- catch子句:“捕获指定类型的所有对象。”
- 过滤子句:“仅当过滤成功时才输入处理程序。”
- finally子句:“处理所有异常并正常退出。”
- 故障子句:“处理所有异常,但不是正常退出。”
鉴于这些简短的解释(引自 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 子句,那么故障子句与 catch 子句有何不同? - C# 编译器是否曾经输出过错误子句?