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 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:
- catch —
catch (FooException) { … } - filter — not available in C# (but in VB.NET as
Catch FooException When booleanExpression) - finally —
finally { … } - fault —
catch { … }
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:
- If
catch { … }really is a catch clause, then how are fault clauses different from catch clauses? - Does the C# compiler ever output fault clauses at all?