C# 4.0 полное руководство - 2011
Шрифт:
На самом деле указывать переменную exOb необязательно. Так, ее необязательно указывать, если обработчику исключений не требуется доступ к объекту исключения, что бывает довольно часто. Для обработки исключения достаточно и его типа. Именно поэтому во многих примерах программ, приведенных в этой главе, переменная exOb опускается.
Следует, однако, иметь в виду, что если исключение не генерируется, то блок оператора try завершается как обычно, и все его операторы catch пропускаются. Выполнение программы возобновляется с первого оператора,
Простой пример обработки исключительной ситуации
Рассмотрим простой пример, демонстрирующий отслеживание и перехватывание исключения. Как вам должно быть уже известно, попытка индексировать массив за его границами приводит к ошибке. Когда возникает подобная ошибка, система CLR генерирует исключение IndexOutOfRangeException, которое определено как стандартное для среды .NET Framework. В приведенной ниже программе такое исключение генерируется намеренно и затем перехватывается.
// Продемонстрировать обработку исключительной ситуации.
using System;
class ExcDemol {
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 подлежит выводу");
}
catch (IndexOutOfRangeException) {
// Перехватить исключение.
Console.WriteLine("Индекс вышел за границы массива!");
}
Console.WriteLine("После блока перехвата исключения.");
}
}
При выполнении этой программы получается следующий результат.
До генерирования исключения.
nums[0]: О
nums[1]: 1
nums[2]: 2
nums[3]: 3
Индекс вышел за границы массива!
После блока перехвата исключения.
В данном примере массив nums типа int состоит из четырех элементов. Но в цикле for предпринимается попытка проиндексировать этот массив от 0 до 9, что и приводит к появлению исключения IndexOutOfRangeException, когда происходит обращение к элементу массива по индексу 4.
Несмотря на всю свою краткость, приведенный выше пример наглядно демонстрирует ряд основных моментов процесса обработки исключительных ситуаций. Во-первых, код, который требуется контролировать на наличие ошибок, содержится в блоке try. Во-вторых, когда возникает исключительная ситуация (в данном случае — при попытке проиндексировать массив nums за его границами в цикле for), в блоке try генерируется исключение, которое затем перехватывается в блоке catch. В этот момент выполнение кода в блоке try завершается и управление передается блоку catch. Это означает, что оператор catch не вызывается специально, а выполнение кода переходит к нему автоматически. Следовательно, оператор, содержащий метод WriteLine и следующий непосредственно за циклом for, где происходит выход индекса за границы массива, вообще не выполняется. А в задачу обработчика исключений входит исправление ошибки, приведшей к исключительной ситуации, чтобы продолжить выполнение программы в нормальном режиме.
Обратите внимание на то, что в операторе catch указан только тип исключения (в данном случае — IndexOutOfRangeException), а переменная исключения отсутствует. Как упоминалось ранее, переменную исключения требуется указывать лишь в том случае, если требуется доступ к объекту исключения. В ряде случаев значение объекта исключения может быть использовано обработчиком исключений для получения дополнительной информации о самой ошибке, но зачастую для обработки исключительной ситуации достаточно просто знать, что она произошла. Поэтому переменная исключения нередко отсутствует в обработчиках исключений, как в рассматриваемом здесь примере.
Как пояснялось ранее, если исключение не генерируется в блоке try, то блок catch не выполняется, а управление программой передается оператору, следующему после блока catch. Для того чтобы убедиться в этом, замените в предыдущем примере программы строку кода
for(int i=0; i < 10; i++) {
на строку
for(int i=0; i < nums.Length; i++) {
Теперь индексирование массива не выходит за его границы в цикле for. Следовательно, никакого исключения не генерируется и блок catch не выполняется.
Второй пример обработки исключительной ситуации
Следует особо подчеркнуть, что весь код, выполняемый в блоке try, контролируется на предмет исключительных ситуаций, в том числе и тех, которые могут возникнуть в результате вызойа метода из самого блока try. Исключение, генерируемое методом в блоке try, может быть перехвачено в том же блоке, если, конечно, этого не будет сделано в самом методе.
В качестве еще одного примера рассмотрим следующую программу, где блок try помещается в методе Main . Из этого блока вызывается метод GenException (), в котором и генерируется исключение IndexOutOfRangeException. Это исключение не перехватывается методом GenException . Но поскольку метод GenException вызывается из блока try в методе Main , то исключение перехватывается в блоке catch, связанном непосредственно с этим блоком try.
/* Исключение может быть сгенерировано одним методом и перехвачено другим. */
using System;
class ExcTest {
// Сгенерировать исключение, public static void GenException {
int[] nums = new int [4];
Console.WriteLine("До генерирования исключения.");
// Сгенерировать исключение в связи с выходом индекса за границы массива.
for(int i=0; i < 10; i++) {