
Лекция 7. Обработка исключительных ситуаций
Какой бы надежный код ни был написан, сколь бы тщательной ни была отладка, в версии, переданной в эксплуатацию и на сопровождение, при запусках будут встречаться нарушения спецификаций(например, форматов ввода данных), ибо если спецификацию можно нарушить, то это событие когда-нибудь да произойдет. В таких исключительных ситуациях продолжение выполнения программы либо становится невозможным (попытка выполнить неразрешенную операцию деления на ноль, попытки записи в защищенную область памяти, попытка открытия несуществующего файла, попытка получить несуществующую запись базы данных), либо в возникшей ситуации применение алгоритма приведет к ошибочным результатам. Что делать при возникновении исключительной ситуации? Конечно, всегда есть стандартный способ - сообщить о возникшей ошибке и прервать выполнение программы. Понятно, что это приемлемо лишь для безобидных приложений; даже для компьютерных игр этот способ не годится, что уж говорить о критически важных приложениях!
Схема обработки исключений в C#
Язык C# наследовал схему исключений языка С++, внеся в нее свои коррективы. Рассмотрим схему подробнее и начнем с синтаксиса конструкции try-catch-finally:
try {...}
catch (T1 e1) {...}
...
catch(Tk ek) {...}
finally {...}
Всюду в тексте модуля, где синтаксически допускается использование блока, этот блок можно сделать охраняемым, добавив ключевое слово try. Вслед за try-блоком могут следовать catch-блоки, называемые блоками-обработчиками исключительных ситуаций, их может быть несколько, они могут и отсутствовать. Завершает эту последовательность finally-блок - блок финализации, который также может отсутствовать. Вся эта конструкция может быть вложенной - в состав try-блока может входить конструкция try-catch-finally.
Выбрасывание исключений. Создание объектов Exception
В теле try-блока может возникнуть исключительная ситуация, приводящая к выбрасыванию исключений. Формально выбрасывание исключения происходит при выполнении оператора throw. Этот оператор, чаще всего, выполняется в недрах операционной системы, когда система команд или функция API не может сделать свою работу. Но этот оператор может быть частью программного текста try-блока и выполняться, когда в результате проведенного анализа становится понятным, что дальнейшая нормальная работа невозможна.
Синтаксически оператор throw имеет вид:
throw[выражение]
Выражение throw задает объект класса, являющегося наследником класса Exception. Обычно это выражение new, создающее новый объект. Если оно отсутствует, то повторно выбрасывается текущее исключение. Если исключение выбрасывается операционной системой, то она сама классифицирует исключение, создает объект соответствующего класса и автоматически заполняет его поля.
В рассматриваемой нами модели исключения являются объектами, класс которых представляет собой наследника класса Exception. Этот класс и многочисленные его наследники является частью библиотеки FCL, хотя и разбросаны по разным пространствам имен. Каждый класс задает определенный тип исключения в соответствии с классификацией, принятой в Framework .Net
В таблице приведены некоторые стандартные типы исключений
Исключение |
Описание |
ArithmeticException |
Основной класс исключений, происходящих при выполнении арифметических операций, таких как DivideByZeroException и OverflowException. |
ArrayTypeMismatchException |
Создается, когда массив не может хранить данный элемент, поскольку фактический тип элемента несовместим с фактическим типом массива. |
DivideByZeroException |
Создается при попытке разделить целое число на ноль. |
IndexOutOfRangeException |
Создается при попытке индексирования массива, если индекс меньше нуля или выходит за границы массива. |
InvalidCastException |
Создается, когда происходит сбой явного преобразования из основного типа в интерфейс либо в производный тип во время выполнения. |
NullReferenceException |
Создается при попытке ссылки на объект, значение которого равно null. |
OutOfMemoryException |
Создается при неудаче попытки выделения памяти с помощью оператора new. Это означает, что память, доступная для среды выполнения, уже исчерпана. |
OverflowException |
Создается
при переполнении арифметической
операции в контексте |
StackOverflowException |
Создается, когда стек выполнения переполнен за счет слишком большого количества вызовов отложенных методов; обычно является признаком очень глубокой или бесконечной рекурсии. |
TypeInitializationException |
Создается,
когда статический конструктор создает
исключение, и не существует ни одного
совместимого предложения |
Имена всех классов исключений заканчиваются словом Exception. Разрешается создавать собственные классы исключений, наследуя их от класса Exception.
При выполнении оператора throw создается объект te, класс TE которого характеризует текущее исключение, а поля содержат информацию о возникшей исключительной ситуации. Выполнение оператора throw приводит к тому, что нормальный процесс вычислений на этом прекращается. Если это происходит в охраняемом try-блоке, то начинается этап "захвата" исключения одним из обработчиков исключений.