При реализации алгоритмов разработчик нередко сталкивается с необходимостью возбуждения исключений при возникновении критических ошибок.
В .NET Framework предусмотрен довольно мощный механизм работы с исключениями, основанный на классе Exception.
Не станем его подробно описывать, так как это выходит за рамки данной статьи и более того всю необходимую информацию можно без труда найти в документации и литературе. Просто вкратце напомним, что класс Exception – базовый класс, представляющий исключительные, которые возникают во время выполнения программы. У него также имеется ряд наследников, которые представляю конкретные разновидности ошибок.
Класс Exception не является абстрактным. Поэтому, если среди его наследников из числа уже изначально имеющихся в составе .NET Framework нет подходящего класса для данной критической ситуации, вполне можно возбудить исключение при помощи его самого.
1 |
throw new Exception("My Exception!"); |
Однако так делать не стоит и вот почему.
Идентификация исключительной ситуации
В сложных проектах довольно редко приходится возбуждать исключения только в одном единственном месте программы. Как правило, таких исключений предусмотрено достаточно много.
Если все они будут представлены одним и тем же классом, при их обработке в блоке try-catch будет практически невозможно распознать, что спровоцировало ошибку в программе.
1 2 3 4 5 6 7 8 |
try { // Делаем что-то } catch (Exception ex) { // Делаем что-то } |
В тоже время эту проблему можно легко решить, создавая собственные классы для исключений.
1 2 3 4 5 6 7 8 9 10 11 12 |
try { // Делаем что-то } catch (MyException1 ex) { // Делаем что-то } catch (MyException2 ex) { // Делаем что-то } |
Расширенное представление исключительной ситуации
В собственный класс исключения можно добавить дополнительные члены для хранения информации об ошибке, которые не предусмотрены в уже имеющихся классах исключений. Что позволяет сделать обработку критических ошибок в программе более простой и гибкой.
Описание своего класса для исключения
Рассмотрим пример создания простейшего класса исключения. Это класс должен соответствовать следующим требованиям:
- Быть наследником класса Exception (необязательно непосредственным);
- Поддерживать сериализацию;
- Содержать набор из четырёх конструкторов.
Ниже приведён код класса исключения, соответствующий всему вышеперечисленному:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
using System; using System.Runtime.Serialization; namespace MyNameSpace { [System.Serializable] class MyException:Exception { public MyException () { } public MyException (string message) : base(message) { } public MyException (string message, Exception inner) : base(message, inner) { } protected MyException (SerializationInfo info, StreamingContext context) : base(info, context) { } } } |
Этот класс совсем небольшой. В нём практически ничего нет, и его не составит труда создать любому программисту. Но, даже этого уже достаточно для представления любой исключительной ситуации.
В случае необходимости в приведённый класс можно включить дополнительные члены для реализации расширенного представления ошибок.
В качестве примера добавим поле, которое будет хранить значение переменной в случае возникновения ошибки.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
using System; using System.Runtime.Serialization; namespace Exc { [System.Serializable] class MyException:Exception { private object _value; public MyException() { } public MyException(string message) : base(message) { } public MyException(string message, Exception inner) : base(message, inner) { } protected MyException(SerializationInfo info, StreamingContext context) : base(info, context) { } public MyException(string message, object value) : base(message) { _value = value; } public object Value { get { return _value; } } } } |
Теперь значение переменной практически любого типа перед возникновением ошибки можно получить непосредственно во время работы программы. Например:
1 2 3 4 5 |
private static void TestMethod() { string s = "abc"; throw new MyException("Ошибка", s); } |
Обработка исключения:
1 2 3 4 5 6 7 8 |
try { TestMethod(); } catch(MyException ex) { label1.Text = ex.Value.ToString(); } |
Поэтому создавая свои классы для исключений, разработчик получает в свои руки мощный инструмент для обработки критических ситуаций в программе.
Добавить комментарий