Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Обработка исключительных ситуаций.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
91 Кб
Скачать
☆

13.12 Перехват исключений производных классов

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

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

В приведенном ниже примере программы создаются два класса исключений: ExceptA и ExceptB. Класс ExceptA является производным от класса Exception, а класс ExceptB  производным от класса ExceptA. Затем в программе генерируются исключения каждого типа. Ради краткости в классах специальных исключений предо­ставляется только один конструктор, принимающий символьную строку, описываю­щую исключение. Но при разработке программ коммерческого назначения в классах специальных исключений обычно требуется предоставлять все четыре конструктора, определяемых в классе Exception.

Листинг 13.15

// Исключения производных классов должны появляться до

// исключения базового класса.

using System;

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

class ExceptA : Exception

{

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

public override string ToString()

{

return Message;

}

}

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

class ExceptB : ExceptA

{

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

public override string ToString() {

return Message;

}

}

class OrderMatters

{

static void Main()

{

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

try {

if(x==0) throw new ExceptA("Перехват исключения типа ExceptA");

else if(x==1) throw new ExceptB("Перехват исключения типа ExceptB");

else throw new Exception();

}

catch (ExceptB exc) {

Console.WriteLine(exc);

}

catch (ExceptA exc) {

Console.WriteLine(exc);

}

catch (Exception exc) {

Console.WriteLine(exc);

}

}

}

}

Вот к какому результату приводит выполнение этой программы.

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

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

System.Exception: Выдано исключение типа "System.Exception".

в OrderMatters.Main() в <имя_файла>:строка 36

Обратите внимание на порядок следования операторов catch. Именно в таком по­рядке они и должны выполняться. Класс ExceptB является производным от класса ExceptA, поэтому исключение типа ExceptB должно перехватываться до исключения типа ExceptA. Аналогично, исключение типа Exception (т.е. базового класса для всех исключений) должно перехватываться последним. Для того чтобы убедиться в этом, измените порядок следования операторов catch. В итоге это приведет к ошибке во время компиляции.

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