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

13.2.3 Второй пример обработки исключительной ситуации

Следует особо подчеркнуть, что весь кол выполняемый в блоке try, контролирует­ся на предмет исключительных ситуаций, в том числе и тех, которые могут возникнуть в результате вызойа метода из самого блока try. Исключение, генерируемое методом в блоке try, может быть перехвачено в том же блоке, если, конечно, этого не будет сделано в самом методе.

В качестве еще одного примера рассмотрим следующую программу, где блок try помещается в методе Main(). Из этого блока вызывается метод GenException(), в ко­тором и генерируется исключение IndexOutOfRangeException. Это исключение не перехватывается методом GenException(). Но поскольку метод GenException() вы­зывается из блока try в методе Main (), то исключение перехватывается в блоке catch, связанном непосредственно с этим блоком try.

Листинг 13.2

/* Исключение может быть сгенерировано одним методом

и перехвачено другим. */

using System;

class ExcTest {

// Сгенерировать исключение.

public static void GenException()

{

int[] nums = new int[4];

Console.WriteLine("До генерирования исключения.");

// Сгенерировать исключение в связи с выходом индекса

// за границы массива.

for(int i=0; i < 10; i++) {

nums[i] = i;

Console.WriteLine("nums[{0}]: {1}", i, nums[i]);

}

Console.WriteLine("Не подлежит выводу");

}

}

class ExcDemo2

{

static void Main()

{

try

{

ExcTest.GenException();

}

catch (IndexOutOfRangeException)

{

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

Console.WriteLine("Индекс вышел за границы массива!");

}

Console.WriteLine("После блока перехвата исключения.");

}

}

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

До генерирования исключения.

nums[0]: 0

nums[1]: 1

nums[2]: 2

nums[3]: 3

Индекс вышел за границы массива!

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

Как пояснялось выше, метод GenException() вызывается из блока try, и поэтому генерируемое им исключение перехватывается не в нем, а в блоке catch внутри мето­да Main(). А если бы исключение перехватывалось в методе GenException(), оно не было бы вообще передано обратно методу Main().

13.3 Последствия неперехвата исключений

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

Листинг 13.3

// Предоставить исполняющей системе C#

// возможность самой обрабатывать ошибки.

using System;

class NotHandled

{

static void Main()

{

int[] nums = new int[4];

Console.WriteLine("До генерирования исключения.");

// Сгенерировать исключение в связи с выходом

// индекса за границы массива.

for(int i=0; i < 10; i++)

{

nums[i] = i;

Console.WriteLine("nums[{0}]: {1}", i, nums[i]);

}

}

}

Когда возникает ошибка индексирования массива, выполнение программы преры­вается и выдается следующее сообщение об ошибке.

Необработанное исключение: System.IndexOutOfRangeException:

Индекс находился вне границ массива.

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

Это сообщение уведомляет об обнаружении в методе NotHandled.Main() необра­ботанного исключения типа System.IndexOutOfRangeException, которое связано с выходом индекса за границы массива.

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

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

Листинг 13.4

// Не сработает!

using System;

class ExcTypeMismatch

{

static void Main()

{

int[] nums = new int[4];

try {

Console.WriteLine("До генерирования исключения.");

// Сгенерировать исключение в связи с выходом

// индекса за границы массива.

for(int i=0; i < 10; i++)

{

nums[i] = i;

Console.WriteLine("nums[{0}]: {1}", i, nums[i]);

}

Console.WriteLine("Не подлежит выводу");

}

/* Если перехват рассчитан на исключение DivideByZeroException,

То перехватить ошибку нарушения границ массива не удастся. */

catch (DivideByZeroException)

{

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

Console.WriteLine("Индекс вышел за границы массива!");

}

Console.WriteLine("После блока перехвата исключения.");

}

}

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

До генерирования исключения.

nums[0] : 0

nums[l] : 1

nums[2] : 2

nums[3] : 3

Необработанное исключение: System.IndexOutOfRangeException:

Индекс находился вне границ массива

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

Как следует из приведенного выше результата, в блоке catch, реагирующем на исключение DivideByZeroException, не удалось перехватить исключение IndexOutOfRangeException.