Чтение онлайн

на главную - закладки

Жанры

Полное руководство. С# 4.0
Шрифт:

Выполнение этой программы приводит к следующему результату. 4/2 равно 2 Делить на нуль нельзя! 16/4 равно 4 32/4 равно 8 Делить на нуль нельзя! 128 / 8 равно 16 Подходящий элемент не найден. Неисправимая ошибка - программа прервана.

В данном примере исключение, обрабатываемое во внутреннем блоке try и связан ное с ошибкой из-за деления на нуль, не мешает дальнейшему выполнению програм мы. Но ошибка нарушения границ массива, обнаруживаемая во внешнем блоке try, приводит к прерыванию программы.

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

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

В приведенных выше примерах перехватывались исключения, генерировавшиеся исполняющей системой автоматически. Но исключение может быть сгенерировано и вручную с помощью оператора throw. Ниже приведена общая форма такого гене рирования: throw exceptOb;

где в качестве exceptOb должен быть обозначен объект класса исключений, произво дного от класса Exception.

Ниже приведен пример программы, в которой демонстрируется применение опе ратора throw для генерирования исключения DivideByZeroException. // Сгенерировать исключение вручную. using System; class ThrowDemo { static void Main { try { Console.WriteLine("До генерирования исключения."); throw new DivideByZeroException; } catch (DivideByZeroException) { Console.WriteLine("Исключение перехвачено."); } Console.WriteLine("После пары операторов try/catch."); } }

Вот к какому результату приводит выполнение этой программы. До генерирования исключения. Исключение перехвачено. После пары операторов try/catch.

Обратите внимание на то, что исключение DivideByZeroException было сге нерировано с использованием ключевого слова new в операторе throw. Не следует забывать, что в данном случае генерируется конкретный объект, а следовательно, он должен быть создан перед генерированием исключения. Это означает, что сгенериро вать исключение только по его типу нельзя. В данном примере для создания объекта DivideByZeroException был автоматически вызван конструктор, используемый по умолчанию, хотя для генерирования исключений доступны и другие конструкторы. Повторное генерирование исключений

Исключение, перехваченное в одном блоке catch, может быть повторно сгенери ровано в другом блоке, чтобы быть перехваченным во внешнем блоке catch. Наиболее вероятной причиной для повторного генерирования исключения служит предоставле ние доступа к исключению нескольким обработчикам. Допустим, что один обработчик оперирует каким-нибудь одним аспектом исключения, а другой обработчик — другим его аспектом. Для повторного генерирования исключения достаточно указать опера тор throw без сопутствующего выражения, как в приведенной ниже форме. throw ;

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

В приведенном ниже примере программы демонстрируется повтор ное генерирование исключения. В данном случае генерируется исключение IndexOutOfRangeException. // Сгенерировать исключение повторно. using System; class Rethrow { public static void GenException { // Здесь массив numer длиннее массива denom. int[] numer = { 4, 8, 16, 32, 64, 128, 256, 512 }; int[] denom = { 2, 0, 4, 4, 0, 8 }; for(int i=0; i<numer.Length; i++) { try { Console.WriteLine(numer[i] + " / " + denom[i] + " равно " + numer[i]/denom[i]); } catch (DivideByZeroException) { Console.WriteLine("Делить

на нуль нельзя!"); } catch (IndexOutOfRangeException) { Console.WriteLine("Подходящий элемент не найден."); throw; // сгенерировать исключение повторно } } } } class RethrowDemo { static void Main { try { Rethrow.GenException; } catch(IndexOutOfRangeException) { // перехватить исключение повторно Console.WriteLine("Неисправимая ошибка - программа прервана."); } } }

В этом примере программы ошибки из-за деления на нуль обрабатываются локаль но в методе GenException, но ошибка выхода за границы массива генерируется повторно. В данном случае исключение IndexOutOfRangeException обрабатывается в методе Main. Использование блока finally

Иногда требуется определить кодовый блок, который будет выполняться после вы хода из блока try/catch. В частности, исключительная ситуация может возникнуть в связи с ошибкой, приводящей к преждевременному возврату из текущего метода. Но в этом методе мог быть открыт файл, который нужно закрыть, или же установлено сетевое соединение, требующее разрывания. Подобные ситуации нередки в програм мировании, и поэтому для их разрешения в C# предусмотрен удобный способ: вос пользоваться блоком finally.

Для того чтобы указать кодовый блок, который должен выполняться после блока try/catch, достаточно вставить блок finally в конце последовательности операторов try/catch. Ниже приведена общая форма совместного использования блоков try/ catch и finally. try { // Блок кода, предназначенный для обработки ошибок. } catch (ExcepType1 exOb) { // Обработчик исключения типа ExcepType1. } catch (ExcepType2 ехОb) { // Обработчик исключения типа ЕхсерТуре2. } finally { // Код завершения обработки исключений. }

Блок finally будет выполняться всякий раз, когда происходит выход из блока try/ catch, независимо от причин, которые к этому привели. Это означает, что если блок try завершается нормально или по причине исключения, то последним выполняется код, определяемый в блоке finally. Блок finally выполняется и в том случае, если любой код в блоке try или в связанных с ним блоках catch приводит к возврату из метода.

Ниже приведен пример применения блока finally. // Использовать блок finally. using System; class UseFinally { public static void GenException(int what) { int t; int[] nums = new int[2]; Console.WriteLine("Получить " + what); try { switch(what) { case 0: t = 10 / what; // сгенерировать ошибку из-за деления на нуль break; case 1: nums[4] = 4; // сгенерировать ошибку индексирования массива break; case 2: return; // возврат из блока try } } catch (DivideByZeroException) { Console.WriteLine("Делить на нуль нельзя!"); return; // возврат из блока catch } catch (IndexOutOfRangeException) { Console.WriteLine("Совпадающий элемент не найден."); } finally { Console.WriteLine("После выхода из блока try."); } } } class FinallyDemo { static void Main { for(int i=0; i < 3; i++) { UseFinally.GenException(i); Console.WriteLine; } } }

Вот к какому результату приводит выполнение этой программы. Получить 0 Делить на нуль нельзя После выхода из блока try. Получить 1 Совпадающий элемент не найден. После выхода из блока try. Получить 2 После выхода из блока try.

Как следует из приведенного выше результата, блок finally выполняется независи мо от причины выхода из блока try.

И еще одно замечание: с точки зрения синтаксиса блок finally следует после блока try, и формально блоки catch для этого не требуются. Следовательно, блок finally можно ввести непосредственно после блока try, опустив блоки catch. В этом случае блок finally начнет выполняться сразу же после выхода из блока try, но исключения обрабатываться не будут. Подробное рассмотрение класса Exception

Поделиться:
Популярные книги

Инвестиго, из медика в маги 2

Рэд Илья
2. Инвестиго
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Инвестиго, из медика в маги 2

Конструктор

Семин Никита
1. Переломный век
Фантастика:
попаданцы
альтернативная история
4.50
рейтинг книги
Конструктор

Блуждающие огни 4

Панченко Андрей Алексеевич
4. Блуждающие огни
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Блуждающие огни 4

Ох уж этот Мин Джин Хо 1

Кронос Александр
1. Мин Джин Хо
Фантастика:
попаданцы
5.00
рейтинг книги
Ох уж этот Мин Джин Хо 1

Черный Маг Императора 11

Герда Александр
11. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Черный Маг Императора 11

Кодекс Крови. Книга ХIV

Борзых М.
14. РОС: Кодекс Крови
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Крови. Книга ХIV

Девочка для Генерала. Книга первая

Кистяева Марина
1. Любовь сильных мира сего
Любовные романы:
остросюжетные любовные романы
эро литература
4.67
рейтинг книги
Девочка для Генерала. Книга первая

Ты не мой Boy 2

Рам Янка
6. Самбисты
Любовные романы:
современные любовные романы
короткие любовные романы
5.00
рейтинг книги
Ты не мой Boy 2

Брачный сезон. Сирота

Свободина Виктория
Любовные романы:
любовно-фантастические романы
7.89
рейтинг книги
Брачный сезон. Сирота

Вор (Журналист-2)

Константинов Андрей Дмитриевич
4. Бандитский Петербург
Детективы:
боевики
8.06
рейтинг книги
Вор (Журналист-2)

Наследник павшего дома. Том IV

Вайс Александр
4. Расколотый мир
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наследник павшего дома. Том IV

Адвокат Империи 2

Карелин Сергей Витальевич
2. Адвокат империи
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Адвокат Империи 2

Законы Рода. Том 6

Flow Ascold
6. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 6

Барон Дубов 4

Карелин Сергей Витальевич
4. Его Дубейшество
Фантастика:
юмористическое фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Барон Дубов 4