Такие сообщения об ошибках полезны для отладки программы, но, по меньшей мере, нежелательны при ее использовании на практике! Именно поэтому так важно организовать обработку исключительных ситуаций в самой программе.
Как упоминалось ранее, тип генерируемого исключения должен соответствовать типу, указанному в операторе catch
. В противном случае исключение не будет перехвачено. Например, в приведенной ниже программе предпринимается попытка перехватить ошибку нарушения границ массива в блоке catch, реагирующем на исключение DivideByZeroException
, связанное с делением на нуль и являющееся еще одним стандартным исключением. Когда индексирование массива выходит за его границы, генерируется исключение IndexOutOfRangeException
, но оно не будет перехвачено блоком catch
, что приведет к аварийному завершению программы.
// Не сработает!
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("He подлежит выводу");
}
/* Если перехват рассчитан на исключение DivideByZeroException, то перехватить ошибку нарушения границ массива не удастся. */
catch (DivideByZeroException) {
// Перехватить исключение.
Console.WriteLine("Индекс вышел за границы массива!");
}
Console.WriteLine("После блока перехвата исключения.");
}
}
Вот к какому результату приводит выполнение этой программы.
До генерирования исключения.
nums[0]: О
nums[1]: 1
nums[2]: 2
nums[3]: 3
Необработанное исключение: System.IndexOutOfRangeException:
Индекс находился вне границ массива в ExcTypeMismatch.Main() в
Как следует из приведенного выше результата, в блоке catch
, реагирующем на исключение DivideByZeroException
, не удалось перехватить исключение IndexOutOfRangeException
.
Обработка исключительных ситуаций - “изящный” способ устранения программных ошибок
Одно из главных преимуществ обработки исключительных ситуаций заключается в том, что она позволяет вовремя отреагировать на ошибку в программе и затем продолжить ее выполнение. В качестве примера рассмотрим еще одну программу, в которой элементы одного массива делятся на элементы другого. Если при этом происходит деление на нуль, то генерируется исключение DivideByZeroException
. Обработка подобной исключительной ситуации заключается в том, что программа уведомляет об ошибке и затем продолжает свое выполнение. Таким образом, попытка деления на нуль не приведет к аварийному завершению программы из-за ошибки при ее выполнении. Вместо этого ошибка обрабатывается "изящно", не прерывая выполнение программы.
// Изящно обработать исключительную ситуацию и продолжить выполнение программы.
using System;
class ExcDemo3 {
static void Main() {
int[] numer = { 4, 8, 16, 32, 64, 128 };
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("Делить на нуль нельзя!");
}
}
}
}
Ниже приведен результат выполнения этой программы.
4/2 равно 2
Делить на нуль нельзя!
16/4 равно 4
32/4 равно 8
Делить на нуль-нельзя!
128 / 8 равно 16