Исключения системного уровня (System.SystemException)
Библиотеки базовых классов .NET определяют множество классов, производных от System.Exception. Пространство имен System определяет базовые объекты ошибок, например ArgumentOutOfRangeException, IndexOutOfRangeException, StackOverflowException и т.д. Другие пространства имен определяют исключения, отражающие поведение своих элементов (например, System.Drawing.Printing определяет исключения, возникающие при печати, System.IO – исключения ввода-вывода, System.Data – исключения, связанные с базами данных и т.д.).
Исключения, генерируемые общеязыковой средой выполнения (CLR), называют исключениями системного уровня. Эти исключения считаются неустранимыми, фатальными ошибками. Исключения системного уровня получаются непосредственно из базового класса System.SystemException, являющегося производным от System.Exception (который, в свою очередь, получается из System.Object).
public class SystemException: Exception {
// Различные конструкторы.
}
С учетом того, что тип System.SystemException не добавляет ничего нового, кроме набора конструкторов, у вас может возникнуть вопрос, почему SystemException оказывается на первом месте. Главная причина в том, что если полученный тип исключения оказывается производным от System.SystemException, вы можете утверждать, что исключение сгенерировано средой выполнения .NET, а не программным кодом выполняемого приложения.
Исключения уровня приложения (System.ApplicationException)
Учитывая то, что все исключения .NET являются типами класса, можно создавать свои собственные исключения, учитывающие специфику приложения. Однако ввиду того, что базовый класс System.SystemException представляет исключения, генерируемые средой CLR, вполне естественно было бы предположить, что пользовательские исключений должны выводиться из типа System.Exception. Это действительно возможно, но практика диктует свой правила, по которым пользовательские исключения лучше выводить из типа System.ApplicationException.
public class ApplicationException: Exception {
// Различные конструкторы.
}
Подобно SystemException, тип ApplicationException не определяет никаких дополнительных членов, кроме набора конструкторов. С точки зрения функциональности единственной целью System.ApplicationException должна быть идентификация источника (устранимой) ошибки. При обработке исключения, полученного из System.ApplicationException, вы можете предполагать, что причиной появления исключения был программный код выполняемого приложения, а не библиотеки базовых классов .NET.
Создание пользовательских исключений, раз…
Всегда есть возможность генерировать экземпляр System.Exceptiоn, чтобы сигнализировать об ошибке времени выполнения (как показано в нашем первом примере), но часто бывает выгоднее построить строго типизированное исключение, которое предоставит уникальную информацию, характеризующую данную конкретную проблему. Предположим, например, что мы хотим создать пользовательское исключение (с именем CarIsDeadException), представляющее ошибку превышения скорости нашего обреченного автомобиля. Первым делом здесь должно быть создание нового класса из System.ApplicationException (по соглашению, классы исключений имеют суффикс "Exception", что в переводе означает "исключение").
// Это пользовательское исключение предлагает описание
// автомобиля, вышедшего из строя.
public class CarIsDeadException: ApplicationException {}
Как и в случае любого другого класса, можно определить пользовательские члены, которые будут затем использоваться в блоке catch в рамках программной логики вызовов. Точно так же можно переопределить любые виртуальные члены, определенные родительскими классами. Например, можно реализовать CarIsDeadException, переопределив виртуальное свойство Message.
public class CarIsDeadException: ApplicationException {
private string messageDetails;
public CarIsDeadException() {}
public CarIsDeadException(string message) {
messageDetails = message;
}
// Переопределение свойства Exception.Message.
public override string Message {
get {
return string.Format("Сообщение об ошибке Car: {0}", messageDetails);
}
}
}
Здесь тип CarIsDeadException предлагает приватный член (messageDetails), представляющий информацию о текущем исключении, которая может быть задана с помощью пользовательского конструктора. Генерировать ошибку с помощью Accelerate() очень просто. Здесь следует разместить, сконфигурировать и сгенерировать тип CarIsDeadException, а не общий тип System.Exception.
// Генерируем пользовательское исключение CarIsDeadException.
Читать дальше