В соответствии с стандартом 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? - Компилятор С# когда-либо выводит предложения о неисправности?