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 | < Назад | Оглавление | Далее > |