Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Ответы по Технологии программирования / Прехват исключений производных классов

.docx
Скачиваний:
7
Добавлен:
21.05.2015
Размер:
7.9 Кб
Скачать

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

Если нужно перехватывать исключения и базового, и производного класса, поместите первой в catch-последовательности инструкцию с заданием производного класса. В противном случае catch-инструкция с заданием базового класса будет перехватывать все исключения производных классов. Это правило — вынужденная мера, поскольку размещение catch-инструкции для базового класса перед остальными catch-инструкциями сделает их недостижимыми, и они никогда не будут выполнены. В С# недостижимая catch-инструкция считается ошибкой.

Следующая программа создает два класса исключений с именами ExceptA и ExceptB. Класс ExceptA выводится из класса ApplicationException, а класс ExceptB — из класса ExceptA. Затем программа генерирует исключение каждого типа.

// Инструкции перехвата исключений производных классов

// должны стоять перед инструкциями перехвата исключений

// базовых классов.

usingSystem;

// Создаем класс исключения.

class ExceptA : ApplicationException {

public ExceptA() : base() { }

public ExceptA(string str) : base(str) { }

public override string ToStringO {

return Message;

}}

// Создаем класс исключения как производный

// от класса ExceptA.

class ExceptB : ExceptA {

public ExceptB() : base() { }

public ExceptB(string str) : base(str) { }

public override string ToStringO {

return Message;

}}

class OrderMatters {

public static void Main() {

for(int x = 0; x < 3; x++) {

try {

if(x==0) throw new ExceptA(

"Перехват исключения типа ExceptA.");

else if(x==l) throw new ExceptB(

"Перехват исключения типа ExceptB.");

else throw new ExceptionO;

}

catch (ExceptBexc) {

// Перехватываем исключение.

Console.WriteLine(exc);

}

catch (ExceptAexc) {

// Перехватываем исключение.

Console.WriteLine(exc);

}

catch (Exception exc) {

Console.WriteLine(exc);

}}}}

Вот результаты выполнения этой программы:

Перехват исключения типа ExceptA.

Перехват исключения типа ExceptB.

System.Exception: Exception of type System.Exception was thrown,

atOrderMatters.Main()

Обратите внимание на порядок следования catch-инструкций. Это — единственно правильный вариант. Поскольку класс ExceptB выведен из класса ExceptA, catch-инструкция для исключений типа ExceptB должна стоять перед инструкцией, предназначенной для перехвата исключений типа ExceptA. Точно так же catch-инструкция для исключений класса Exception (который является базовым для всех исключений) должна стоять последней. Чтобы убедиться в этом, попробуйте переставить catch-инструкции в другом порядке. Это приведет к ошибке при компиляции.

Часто catch-инструкцию, определенную для исключений базового класса, успешно используют для перехвата целой категории исключений. Предположим, вы создаете набор исключений для некоторого устройства. Если вывести все эти исключения из общего базового класса, то приложения, которым не требуется подробные сведения о возникшей проблеме, могли бы просто перехватывать исключение, настроенное на базовый класс, избегнув тем самым ненужного дублирования кода.