Книга: C# 4.0: полное руководство

Генерирование исключений вручную

Генерирование исключений вручную

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

throw exceptOb;

где в качестве exceptOb должен быть обозначен объект класса исключений, производного от класса Exception.

Ниже приведен пример программы, в которой демонстрируется применение оператора throw для генерирования исключения DivideByZeroException.

// Сгенерировать исключение вручную.
using System;
class ThrowDemo {
  static void Main() {
    try {
      Console.WriteLine("До генерирования исключения.");
      throw new DivideByZeroException();
    }
    catch (DivideByZeroException) {
      Console.WriteLine("Исключение перехвачено.");
    }
    Console.WriteLine("После пары операторов try/catch.");
  }
}

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

До генерирования исключения.
Исключение перехвачено.
После пары операторов try/catch.

Обратите внимание на то, что исключение DivideByZeroException было сгенерировано с использованием ключевого слова new в операторе throw. Не следует забывать, что в данном случае генерируется конкретный объект, а следовательно, он должен быть создан перед генерированием исключения. Это означает, что сгенерировать исключение только по его типу нельзя. В данном примере для создания объекта DivideByZeroException был автоматически вызван конструктор, используемый по умолчанию, хотя для генерирования исключений доступны и другие конструкторы.

Повторное генерирование исключений

Исключение, перехваченное в одном блоке catch, может быть повторно сгенерировано в другом блоке, чтобы быть перехваченным во внешнем блоке catch. Наиболее вероятной причиной для повторного генерирования исключения служит предоставление доступа к исключению нескольким обработчикам. Допустим, что один обработчик оперирует каким-нибудь одним аспектом исключения, а другой обработчик — другим его аспектом. Для повторного генерирования исключения достаточно указать оператор throw без сопутствующего выражения, как в приведенной ниже форме.

throw ;

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

В приведенном    ниже    примере программы демонстрируется    повторное генерирование    исключения. В данном случае генерируется    исключение IndexOutOfRangeException.

// Сгенерировать исключение повторно.
using System;
class Rethrow {
  public static void GenException() {
    // Здесь массив numer длиннее массива denom.
    int[] numer = { 4, 8, 16, 32, 64, 128, 256, 512 };
    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("Делить на нуль нельзя!");
      }
      catch (IndexOutOfRangeException) {
        Console.WriteLine("Подходящий элемент не найден.");
        throw; // сгенерировать исключение повторно
      }
    }
  }
}
class RethrowDemo {
  static void Main() {
    try {
      Rethrow.GenException();
    }
    catch(IndexOutOfRangeException) {
      // перехватить исключение повторно
      Console.WriteLine("Неисправимая ошибка - программа прервана.");
    }
  }
}

В этом примере программы ошибки из-за деления на нуль обрабатываются локально в методе GenException(), но ошибка выхода за границы массива генерируется повторно. В данном случае исключение IndexOutOfRangeException обрабатывается в методе Main().

Оглавление книги


Генерация: 1.145. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз