Чтение онлайн

ЖАНРЫ

C# 4.0 полное руководство - 2011

Шилдт Герберт

Шрифт:

Следует также заметить, что в четвертом конструкторе класса Exception типы Serializationlnfo и StreamingContext относятся к пространству имен System. Runtime.Serialization.

Наиболее часто используемые исключения

В пространстве имен System определено несколько стандартных, встроенных исключений. Все эти исключения являются производными от класса SystemException, поскольку они генерируются системой CLR при появлении ошибки во время выполнения. В табл. 13.1 перечислены некоторые наиболее часто используемые стандартные исключения.

Таблица 13.1. Наиболее часто используемые

исключения, определенные в пространстве имен System

Исключение

Значение

ArrayTypeMismatchException

Тип сохраняемого значения несовместим с типом массива

DivideByZeroException

Попытка деления на нуль

IndexOutOfRangeException

Индекс оказался за границами массива

InvalidCastException

Неверно выполнено динамическое приведение типов

OutOfMemoryException

Недостаточно свободной памяти для дальнейшего выполнения программы. Это исключение может быть, например, сгенерировано, если для создания объекта с помощью оператора new не хватает памяти

OverflowException

Произошло арифметическое переполнение

NullReferenceException

Попытка использовать пустую ссылку, т.е. ссылку, которая не указывает ни на один из объектов

Большинство исключений, приведенных в табл. 13.1, не требует особых пояснений, кроме исключения NullReferenceException. Это исключение генерируется при попытке использовать пустую ссылку на несуществующий объект, например, при вызове метода по пустой ссылке. Пустой называется такая ссылка, которая не указывает ни на один из объектов. Для того чтобы создать такую ссылку, достаточно, например, присвоить явным образом пустое значение переменной ссылочного типа, используя ключевое слово null. Пустые ссылки могут также появляться и другими, менее очевидными путями. Ниже приведен пример программы, демонстрирующий обработку исключения NullReferenceException.

// Продемонстрировать обработку исключения NullReferenceException.

using System;

class X { int x;

public X(int a) { x = a;

}

public int Add(X o) { return x + o.x;

}

}

// Продемонстрировать генерирование и обработку // исключения NullReferenceException. class NREDemo {

static void Main {

X p = new X(10);

X q = null; // присвоить явным образом пустое значение переменной q int val;

try {

val = p.Add(q); // эта операция приведет к исключительной ситуации } catch (NullReferenceException) {

Console.WriteLine("Исключение NullReferenceException!");

Console.WriteLine("Исправление ошибки...\n");

// А теперь исправить ошибку, q = new X(9); val = p.Add(q);

}

Console.WriteLine("Значение val равно {0}", val);

}

}

Вот к какому результату приводит выполнение этой программы.

Исключение NullReferenceException!

Исправление ошибки...

Значение val равно 19

В

приведенном выше примере программы создается класс X, в котором определяются член
х и метод Add , складывающий значение члена х в вызывающем объекте со значением члена х в объекте, передаваемом этому методу в качестве параметра. Оба объекта класса X создаются в методе Main . Первый из них (переменная р) инициализируется, а второй (переменная q) — нет. Вместо этого переменной q присваивается пустое значение. Затем вызывается метод р. Add с переменной q в качестве аргумента. Но поскольку переменная q не ссылается ни на один из объектов, то при попытке получить значение члена q. х генерируется исключение NullReferenceException.

Получение производных классов исключений

Несмотря на то что встроенные исключения охватывают наиболее распространенные программные ошибки, обработка исключительных ситуаций в C# не ограничивается только этими ошибками. В действительности одна из сильных сторон принятого в C# подхода к обработке исключительных ситуаций состоит в том, что в этом языке допускается использовать исключения, определяемые пользователем, т.е. тем, кто программирует на С#. В частности, такие специальные исключения можно использовать для обработки ошибок в собственном коде, а создаются они очень просто. Для этого достаточно определить класс, производный от класса Exception. В таких классах совсем не обязательно что-то реализовывать — одного только их существования в системе типов уже достаточно, чтобы использовать их в качестве исключений.

ПРИМЕЧАНИЕ

В прошлом специальные исключения создавались как производные от класса Application.Exception, поскольку эта иерархия классов была первоначально зарезервирована для исключений прикладного характера. Но теперь корпорация Microsoft не рекомендует этого делать, а вместо этого получать исключения, производные от класса Exception. Именно по этой причине данный подход и рассматривается в настоящей книге.

Создаваемые пользователем классы будут автоматически получать свойства и методы, определенные в классе Exception и доступные для них. Разумеется, любой из этих членов класса Exception можно переопределить в создаваемых классах исключений.

Когда создается собственный класс исключений, то, как правило, желательно, чтобы в нем поддерживались все конструкторы, определенные в классе Exception. В простых специальных классах исключений этого нетрудно добиться, поскольку для этого достаточно передать подходящие аргументы соответствующему конструктору класса Exception, используя ключевое слово base. Но формально нужно предоставить только те конструкторы, которые фактически используются в программе.

Рассмотрим пример программы, в которой используется исключение специального типа. Напомним, что в конце главы 10 был разработан класс RangeArray, поддерживающий одномерные массивы, в которых начальный и конечный индексы определяются пользователем. Так, например, вполне допустимым считается массив, индексируемый в пределах от -5 до 27. Если же индекс выходил за границы массива, то для обработки этой ошибки в классе RangeArray была определена специальная переменная. Такая переменная устанавливалась и проверялась после каждой операции обращения к массиву в коде, использовавшем класс RangeArray. Безусловно, такой подход к обработке ошибок "неуклюж" и чреват дополнительными ошибками. В приведенном ниже улучшенном варианте класса RangeArray обработка ошибок нарушения границ

Поделиться с друзьями: