Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharp Language Specification.doc
Скачиваний:
13
Добавлен:
26.09.2019
Размер:
4.75 Mб
Скачать

8.10Оператор try

Оператор try предлагает механизм перехвата исключений, происходящих в ходе выполнения блока. Кроме того, оператор try дает возможность определить блок кода, который должен всегда выполняться при передаче управления за пределы оператора try.

оператор_try: try блок предложения_catch try блок предложение_finally try блок предложения_catch предложение_ finally

предложения_catch: конкретные_предложения_catch общее_предложение_catchнеобязательно конкретные_предложения_catchнеобязательно общее_предложение_catch

конкретные_предложения_catch: конкретное_предложение_catch конкретные_предложения_catch конкретное_предложение_catch

конкретное_предложение_catch: catch ( тип_класса идентификаторнеобязательно ) блок

общее_предложение_catch: catch блок

предложение_finally: finally блок

Существует три вида операторов try:

  • блок try, за которым следует один или несколько блоков catch;

  • блок try, за которым следует блок finally;

  • блок try, за которым следует один или несколько блоков catch и затем блок finally.

Если в предложении catch указывается тип_класса, это должен быть тип System.Exception, производный тип от System.Exception или тип параметра типа, чей эффективный базовый класс — System.Exception (или его подкласс).

Когда в предложении catch указывается и тип_класса, и идентификатор, тем самым объявляется переменная исключения с данным именем и типом. Переменная исключения соответствует локальной переменной с областью видимости, охватывающей блок catch. В ходе выполнения блока catch переменная исключения представляет обрабатываемое при этом исключение. Для контроля определенного присваивания считается, что в пределах всей области видимости переменной исключения для нее обеспечено определенное присваивание.

Доступ к объекту исключения в блоке catch невозможен, если имя переменной исключения не включено в предложение catch.

Предложение catch, в котором не указан ни тип исключения, ни имя переменной исключения, называется общим предложением catch. Оператор try может содержать только одно общее предложение catch, и если оно имеется, оно должно быть последним предложением catch.

В некоторых языках программирования поддерживаются исключения, которые не могут быть представлены объектами, производными от System.Exception, хотя такие исключения не генерируются кодом C#. Общее предложение catch позволяет перехватывать подобные исключения. Таким образом, общее предложение catch семантически отличается от предложения с указанным типом System.Exception тем, что первое может также перехватывать исключения в программах на других языках.

В поисках обработчика для исключения производится анализ предложений catch в лексикографическом порядке. Если в предложении catch указан тот же тип, что и в одном из предыдущих предложений catch того же оператора try (или производный от него), возникает ошибка времени компиляции. Такое ограничение позволяет избежать появления недостижимых предложений catch.

Внутри блока catch с помощью оператора throw (§8.9.5) без выражения можно повторно сгенерировать исключение, перехваченное блоком catch. Присваивание значений переменной исключения не изменяет повторно генерируемого исключения.

В этом примере

using System;

class Test { static void F() { try { G(); } catch (Exception e) { Console.WriteLine("Exception in F: " + e.Message); e = new Exception("F"); throw; // re-throw } }

static void G() { throw new Exception("G"); }

static void Main() { try { F(); } catch (Exception e) { Console.WriteLine("Exception in Main: " + e.Message); } } }

метод F перехватывает исключение, выводит на консоль диагностическую информацию, изменяет переменную исключения и повторно генерирует исключение. Поскольку повторно генерируется исходное исключение, выводится следующее:

Exception in F: G Exception in Main: G

Если бы первый блок catch сгенерировал исключение e вместо повторения текущего исключения, было бы выведено следующее:

Exception in F: G Exception in Main: F

Для операторов break, continue и goto передача управления за пределы блока finally вызывает ошибку времени компиляции. Если оператор break, continue или goto включен в блок finally, цель оператора должна находиться в этом же блоке finally, иначе возникнет ошибка времени компиляции.

Кроме того, ошибка времени компиляции распознается при включении оператора return в блок finally.

Оператор try выполняется следующим образом.

  • Управление передается в блок try.

  • Если управление достигает конечной точки блока try, то:

  • если в операторе try имеется блок finally, выполняется блок finally;

  • управление передается в конечную точку оператора try;

  • Если во время выполнения блока try исключение распространяется в оператор try, происходит следующее.

  • Предложения catch, если они имеются, проверяются в порядке их следования в поисках подходящего обработчика для исключения. Первое предложение catch, в котором указан тип исключения или базовый тип для типа исключения, считается подходящим вариантом. Общее предложение catch считается подходящим для любого типа исключения. Если подходящее предложение catch найдено, то:

  • если в найденном предложении catch объявляется переменная исключения, ей присваивается объект исключения;

  • управление передается в найденный блок catch;

  • если управление достигает конечной точки блока catch:

  • если в операторе try имеется блок finally, выполняется блок finally;

  • управление передается в конечную точку оператора try;

  • если во время выполнения блока catch исключение распространяется в оператор try:

  • если в операторе try имеется блок finally, выполняется блок finally;

  • исключение распространяется в следующий объемлющий оператор try.

  • Если в операторе try нет предложений catch или ни одно из предложений catch не подходит для исключения, то:

  • если в операторе try имеется блок finally, выполняется блок finally;

  • исключение распространяется в следующий объемлющий оператор try.

Операторы блока finally всегда выполняются после передачи управления за пределы оператора try. Это правило соблюдается независимо от того, передается ли управление в обычном потоке выполнения, в результате выполнения оператора break, continue, goto или return, или в результате распространения исключения за пределы оператора try.

Если во время выполнения блока finally генерируется исключение, которое не перехватывается в том же блоке finally, исключение распространяется в следующий объемлющий оператор try. Если в этот момент распространялось другое исключение, оно теряется. Процесс распространения исключения рассматривается далее в описании оператора throw (§8.9.5).

Блок try оператора try считается достижимым, если достижим оператор try.

Блок catch оператора try считается достижимым, если достижим оператор try.

Блок finally оператора try считается достижимым, если достижим оператор try.

Конечная точка оператора try достижима, если выполнены следующие два условия:

  • достижима конечная точка блока try или по крайней мере одного блока catch;

  • достижима конечная точка блока finally, если он имеется.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]