В прошлом специальные исключения создавались как производные от класса Application.Exception, поскольку эта иерархия классов была первоначально зарезервирована для исключений прикладного характера. Но теперь корпорация Microsoft не рекомендует этого делать, а вместо этого получать исключения, производные от класса Exception. Именно по этой причине данный подход и рассматривается в настоящей книге.
------------------------------------
Создаваемые пользователем классы будут автоматически получать свойства и методы, определенные в классе Exception
и доступные для них. Разумеется, любой из этих членов класса Exception
можно переопределить в создаваемых классах исключений.
Когда создается собственный класс исключений, то, как правило, желательно, чтобы в нем поддерживались все конструкторы, определенные в классе Exception
. В простых специальных классах исключений этого нетрудно добиться, поскольку для этого достаточно передать подходящие аргументы соответствующему конструктору класса Exception
, используя ключевое слово base
. Но формально нужно предоставить только те конструкторы, которые фактически используются в программе.
Рассмотрим пример программы, в которой используется исключение специального типа. Напомним, что в конце главы 10 был разработан класс RangeArray
, поддерживающий одномерные массивы, в которых начальный и конечный индексы определяются пользователем. Так, например, вполне допустимым считается массив, индексируемый в пределах от -5 до 27. Если же индекс выходил за границы массива, то для обработки этой ошибки в классе RangeArray
была определена специальная переменная. Такая переменная устанавливалась и проверялась после каждой операции обращения к массиву в коде, использовавшем класс RangeArray
. Безусловно, такой подход к обработке ошибок "неуклюж" и чреват дополнительными ошибками. В приведенном ниже улучшенном варианте класса RangeArray
обработка ошибок нарушения границ массива выполняется более изящным и надежным способом с помощью специально генерируемого исключения.
// Использовать специальное исключение для обработки
// ошибок при-обращении к массиву класса RangeArray.
using System;
// Создать исключение для класса RangeArray.
class RangeArrayException : Exception {
/* Реализовать все конструкторы класса Exception. Такие конструкторы просто реализуют конструктор базового класса. А поскольку класс исключения RangeArrayException ничего не добавляет к классу Exception, то никаких дополнительных действий не требуется. */
public RangeArrayException() : base() { }
public RangeArrayException(string str) : base(str) { }
public RangeArrayException(
string str, Exception inner) : base(str, inner) { }
protected RangeArrayException(
System.Runtime.Serialization.SerializationInfo si,
System.Runtime.Serialization.StreamingContext sc) : base(si, sc) { }
// Переопределить метод ToString()
// для класса исключения RangeArrayException.
public override string ToString() {
return Message;
}
}
// Улучшенный вариант класса RangeArray.
class RangeArray {
// Закрытые данные.
int[] a; // ссылка на базовый массив
int lowerBound; // наименьший индекс
int upperBound; // наибольший индекс
// Автоматически реализуемое и доступное
// только для чтения свойство Length,
public int Length { get; private set; }
// Построить массив по заданному размеру
public RangeArray(int low, int high) {
high++;
if(high <= low) {
throw new RangeArrayException("Нижний индекс не меньше верхнего.");
}
a = new int[high - low];
Length = high - low;
lowerBound = low;