Перехват исключений
Принимая во внимание, что .NET Framework включает большое количество предопределенных классов исключений, возникает вопрос: как их использовать в коде для перехвата ошибочных условий? Для того чтобы справиться с возможными ошибочными ситуациями в коде C#, программа обычно делится на блоки трех разных типов:
-
Блоки try инкапсулируют код, формирующий часть нормальных действий программы, которые потенциально могут столкнуться с серьезными ошибочными ситуациями.
-
Блоки catch инкапсулируют код, который обрабатывает ошибочные ситуации, происходящие в коде блока try. Это также удобное место для протоколирования ошибок.
-
Блоки finally инкапсулируют код, очищающий любые ресурсы или выполняющий другие действия, которые обычно нужно выполнить в конце блоков try или catch. Важно понимать, что этот блок выполняется независимо от того, сгенерированo исключение или нет.
Try и catch
Основу обработки исключительных ситуаций в C# составляет пара ключевых слов try и catch. Эти ключевые слова действуют совместно и не могут быть использованы порознь. Ниже приведена общая форма определения блоков try/catch для обработки исключительных ситуаций:
try { // Блок кода, проверяемый на наличие ошибок. } catch (ExcepType1 exOb) { // Обработчик исключения типа ExcepType1. } catch (ExcepType2 exOb) { // Обработчик исключения типа ExcepType2. } ...
где ExcepType — это тип возникающей исключительной ситуации. Когда исключение генерируется оператором try, оно перехватывается составляющим ему пару оператором catch, который затем обрабатывает это исключение. В зависимости от типа исключения выполняется и соответствующий оператор catch. Так, если типы генерируемого исключения и того, что указывается в операторе catch, совпадают, то выполняется именно этот оператор, а все остальные пропускаются. Когда исключение перехватывается, переменная исключения exOb получает свое значение. На самом деле указывать переменную exOb необязательно. Так, ее необязательно указывать, если обработчику исключений не требуется доступ к объекту исключения, что бывает довольно часто. Для обработки исключения достаточно и его типа.
Следует, однако, иметь в виду, что если исключение не генерируется, то блок оператора try завершается как обычно, и все его операторы catch пропускаются. Выполнение программы возобновляется с первого оператора, следующего после завершающего оператора catch. Таким образом, оператор catch выполняется лишь в том случае, если генерируется исключение.
Давайте рассмотрим пример, в котором будем обрабатывать исключение, возникающее при делении числа на 0:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static int MyDel(int x, int y) { return x / y; } static void Main() { link1: try { Console.Write("Введите x: "); int x = int.Parse(Console.ReadLine()); Console.Write("Введите y: "); int y = int.Parse(Console.ReadLine()); int result = MyDel(x, y); Console.WriteLine("Результат: " + result); } // Обрабатываем исключение возникающее при делении на ноль catch (DivideByZeroException) { Console.WriteLine("Деление на 0 detected!!!\n"); goto link1; } // Обрабатываем исключение при неккоректном вводе числа в консоль catch (FormatException) { Console.WriteLine("Это НЕ число!!!\n"); goto link1; } Console.ReadLine(); } } }
Данный простой пример наглядно иллюстрирует обработку исключительной ситуации при делении на 0 (DivideByZeroException), а так же пользовательскую ошибку при вводе не числа (FormatException).
Последствия неперехвата исключений
Перехват одного из стандартных исключений, как в приведенном выше примере, дает еще одно преимущество: он исключает аварийное завершение программы. Как только исключение будет сгенерировано, оно должно быть перехвачено каким-то фрагментом кода в определенном месте программы. Вообще говоря, если исключение не перехватывается в программе, то оно будет перехвачено исполняющей системой. Но дело в том, что исполняющая система выдаст сообщение об ошибке и прервет выполнение программы.
Например, если убрать из предыдущего примера исключение FormatException, то при вводе неккоректной строки, IDE-среда VisualStudio выдаст предупреждающее сообщение:
Такие сообщения об ошибках полезны для отладки программы, но, по меньшей мере, нежелательны при ее использовании на практике! Именно поэтому так важно организовать обработку исключительных ситуаций в самой программе.
Комментарии