В соответствии с стандартом CLI (раздел IIA, глава 19) и справочной страницей MSDN для System.Reflection.ExceptionHandlingClauseOptions
enum, существует четыре разных типа блоков обработчиков исключений:
- catch: "Поймать все объекты указанного типа".
- фильтр: "Введите обработчик только в том случае, если фильтр успешно завершен".
- finally: "Обработать все исключения и нормальный выход".
- fault: "Обработка всех исключений, но не нормальный выход".
Учитывая эти краткие объяснения (цитируемые из стандарта CLI, кстати), они должны отображаться на С# следующим образом:
- catch —
catch (FooException) { … }
- фильтр — недоступен в С# (но в VB.NET как
Catch FooException When booleanExpression
) - наконец —
finally { … }
- ошибка —
catch { … }
Эксперимент:
Простой эксперимент показывает, что это сопоставление не является компилятором .NET С#:
// 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? - Компилятор С# когда-либо выводит предложения о неисправности?