netlib.narod.ru< Назад | Оглавление | Далее >

Обработка исключений

Разные ОС, графические среды, библиотеки и функции по-разному сообщают об ошибках. Одни возвращают логические значения, другие — коды ошибок, третьи — значение NULL, четвертые подают звуковой сигнал, пятые приводят к аварийному сбою системы.

В С# и .NET Framework для сообщения об ошибках предпринята попытка унифицировать использование технологии структурной обработки исключений (structured exception handling).

Чтобы изучить ее, начнем с того, что в программе CsDateClass присвоим полю month объекта Date значение 13:

  mydate.month = 13;

Перекомпилируйте и запустите программу. Если откроется диалоговое окно выбора отладчика, щелкните по кнопке No. Вы получите в командной строке сообщение:

  Unhandled Exception: System.IndexOutOfRangeException: Index was outside the
  bounds of the array.
      at Date.DayOfYear()
      at CsDateClass.Main()

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

Заметьте, что сообщение правильно: индекс массива MonthDays, действительно, вне границ массива. В языке С проблемы такого рода приводили к другим видам ошибок, например, к переполнению стека. С# выполняет проверку корректности индекса перед доступом к элементу массива по его индексу. Программа реагирует на неправильный индекс, инициируя простой процесс, который называется выбросом (throwing) или генерацией исключения.

В С# есть очень полезная возможность — сделать так, чтобы программы сами определяли возникновение исключений и обрабатывали их. Когда программа проверяет возникновение исключения, говорят, что она перехватывает (catch) исключение. Для перехвата исключения операторы, которые могут вызвать исключение, помещаются в блок try, а операторы, выполняемые при обработке исключения, — в блок catch. Например, чтобы учитывать возможность указания неправильной даты, в программу CsDateClass можно поместить такой код:

  try
  {
      Console. WriteLine("Day of year = {0}", mydate.DayOfYear());
  }
  catch (Exception exc)
  {
      Console. WriteLine(exc);
  }

Класс Exception определен в пространстве имен System, a exc — объект типа Exception, определенный в программе. Этот объект получает информацию об исключении. В данном примере я просто передал ехс методу Console.WriteLine в качестве параметра. При задании неправильного месяца этот оператор покажет точно такой же блок текста с описанием ошибки, как тот, что я показывал ранее. Но теперь программа не завершается преждевременно, и можно обрабатывать ошибку более изящно.

Даже одна строка кода может вызвать исключения разных типов. Поэтому можно определить несколько разных блоков catch:

  try
  {
      ...
  }
  catch (NullReferenceException exc)
  {
      ...
  }
  catch (ArgumentOutOfRangeException exc)
  {
      ...
  }
  catch (Exception exc)
  {
      ...
  }

Обратите внимание, что исключение самого общего типа находится в конце.

Можно также добавить блок finally:

  try
  {
      ...
  }
  catch (Exception exc)
  {
      ...
  }
  finally
  {
      ...
  }

Независимо от того, возникнет исключение или нет, код блока finally все равно выполнится: после кода блока catch (если исключение возникнет) или после кода блока try (если нет). В блок finally можно поместить, например, код освобождения ресурсов.

Вы можете спросить: «А зачем блок finally? Разве нельзя просто поместить код освобождения ресурсов после блока catch?» Можно. Но вы можете закончить блок try или catch оператором goto. В этом случае код блока finally все равно выполнится перед выполнением оператора goto.

Можно также пропустить блок catch:

  try
  {
      ...
  }
  finally
  {
      ...
  }

В этом случае вы увидите окно с информацией об отладчике и текстовым описанием исключения (тем же, что мы показывали при помощи Console.WriteLine), затем выполнится код блока finally, и программа завершится нормально.


netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz