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

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

Жанры

ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание

Троелсен Эндрю

Шрифт:

static void Main(string[] args) {

 …

 try {

for (int i = 0; i ‹ 10; i++) myCar.Accelerate(10);

 } catch {

Console.WriteLine("Случилось что-то ужасное…");

 }

 …

}

Очевидно, что это не самый информативный способ обработки исключения, поскольку здесь вы не имеете возможности получить содержательную информацию о произошедшей

ошибке (например, имя метода, содержимое стека вызовов или пользовательское сообщение). Тем не менее, в C# такая конструкция возможна.

Генерирование вторичных исключений

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

// Перекладывание ответственности.

static void Main (string[] args) {

 …

 try {

// Логика ускорения автомобиля… }

catch(CarIsDeadException e) {

// Частичная обработка ошибки и перенаправление.

// Здесь перенаправляется входной объект CarIsDeadException.

// Но можно генерировать и другое исключение.

throw e;

 }

 …

}

Вы должны понимать, что в данном примере программного кода конечным получателем CarIsDeadException является среда CLR, поскольку здесь вторичное исключение генерируется методом Main. Поэтому вашему конечному пользователю будет представлено системное диалоговое окно с информацией об ошибке. Как правило, вторично сгенерированное и частично обработанное исключение предъявляется вызывающей стороне, которая имеет возможность обработать его более "грациозно".

Внутренние исключения

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

catch(CarlsDeadException e) {

 // Попытка открыть файл carErrors.txt на диске C.

 FileStream fs = File.Open(@"C:\carErrors.txt", FileMode.Open);

 …

}

Если указанный файл на диске C не найден, попытка вызова File.Open даст в результате FileNotFoundException. Позже мы рассмотрим пространство имен System.IO и выясним, как перед открытием файла можно программными средствами проверить наличие файла на жестком диске (и предотвратить возможность возникновения исключения). Однако здесь, чтобы сосредоточиться

на теме исключений, мы предполагаем, что исключение возникло.

Когда во время обработки одного исключения обнаруживается другое исключение, лучше всего записать новый объект исключения, как "внутреннее исключение" в рамках нового объекта того же типа, что и исходное исключение (язык сломаешь!). Причина, по которой мы должны создавать новый объект исключения, заключается в том, что единственным способом документирования внутреннего исключения оказывается использование параметров конструктора. Рассмотрите следующий фрагмент программного кода.

catch (CarIsDeadException e) {

 try {

FileStream fs = File.Open(@"C:\carErrors.txt", FileMode.Open);

 } catch(Exception e2) {

// Генерирование исключения, записывающего новое исключение

// и сообщение первого исключения.

throw new CarIsDeadException(e.Message, e2);

 }

}

Заметьте, что в данном случав мы передали объект FileNotFoundException конструктору CarIsDeadException в виде второго параметра. Сконфигурировав этот новый объект, мы направляем его по стеку вызовов следующему вызывающему объекту, в данном случае по отношению к методу Main.

С учетом того, что после Main "следующих вызывающих объектов" для обработки исключений нет, мы снова должны увидеть диалоговое окно с сообщением об ошибке. Во многом подобно генерированию вторичных исключений, запись внутренних исключений обычно оказывается полезной только тогда, когда вызывающий объект имеет возможность красиво обработать такое исключение. В этом случае логика catch вызывающей стороны может использовать свойство InnerException для получения подробной информации об объекте внутреннего исключения.

Блок finally

В рамках try/catch можно также определить необязательный блок finally. Задача блока finally – обеспечить безусловное выполнение некоторого набора операторов программного кода, независимо от наличия или отсутствия исключения (любого типа). Для примера предположим, что вы хотите всегда выключать радио автомобиля перед выходом из Main, независимо от исключений.

static void Main(string[] args) {

 …

 Car myCar = new Car ('"Zippy", 20);

 myCar.CrankTunes(true);

 try {

// Логика ускорения автомобиля.

 } catch (CarIsDeadException e) {

// Обработка CarIsDeadException.

 } catch (ArgumentOutOfRangeException e) {

// Обработка ArgumentOutOfRangeException.

 } catch(Exception e) {

// Обработка всех остальных исключений.

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

Идеальный мир для Лекаря 8

Сапфир Олег
8. Лекарь
Фантастика:
юмористическое фэнтези
аниме
7.00
рейтинг книги
Идеальный мир для Лекаря 8

Последняя Арена 6

Греков Сергей
6. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Последняя Арена 6

По воле короля

Леви Кира
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
По воле короля

Душелов. Том 4

Faded Emory
4. Внутренние демоны
Фантастика:
юмористическая фантастика
ранобэ
фэнтези
фантастика: прочее
хентай
эпическая фантастика
5.00
рейтинг книги
Душелов. Том 4

Темный Лекарь 2

Токсик Саша
2. Темный Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Темный Лекарь 2

Эволюция мага

Лисина Александра
2. Гибрид
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Эволюция мага

(Не) моя ДНК

Рымарь Диана
6. Сапфировые истории
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
(Не) моя ДНК

Протокол "Наследник"

Лисина Александра
1. Гибрид
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Протокол Наследник

Измена. Наследник для дракона

Солт Елена
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Измена. Наследник для дракона

Неудержимый. Книга II

Боярский Андрей
2. Неудержимый
Фантастика:
городское фэнтези
попаданцы
5.00
рейтинг книги
Неудержимый. Книга II

Камень. Книга 4

Минин Станислав
4. Камень
Фантастика:
боевая фантастика
7.77
рейтинг книги
Камень. Книга 4

Измена. Право на сына

Арская Арина
4. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Право на сына

Инквизитор Тьмы 4

Шмаков Алексей Семенович
4. Инквизитор Тьмы
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Инквизитор Тьмы 4

Кротовский, сколько можно?

Парсиев Дмитрий
5. РОС: Изнанка Империи
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Кротовский, сколько можно?