Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
33
Добавлен:
29.02.2016
Размер:
5 Mб
Скачать

Оператор try

В С# исключения представляются классами. Все классы исключений порождены от встроенного класса исключений Exception, который определен в пространстве имен System. В языке программирования С# предусмотрен специальный синтаксис для Structured Exception Handling (SEH структурированной обработки исключительных ситуаций). Существуют специальные ключевые слова, позволяющие помечать участки кода как участки, в которых допустима обработка исключительных ситуаций, и размещать инструкции, указывающие, что следует делать при возникновении исключительной ситуации. Для этих целей используются три ключевых слова:try,catchиfinally. Каждому из них соответствует некоторый блок кода, и все они должны помещаться в последовательно расположенных строках кода.

Управление обработкой исключений основывается на использовании оператора try. Синтаксис оператора:

try // контролируемый блок

{

}

catch//один или несколько блоков обработки исключений

{

}

finally//блок завершения

{

}

Существует также возможность использовать блоки try и finally без блока catch, а также блок try с несколькими блоками catch. Если имеется один или несколько блоков catch, то блок finally является необязательным, в противном случае он обязателен.

Эти блоки используются следующим образом:

• try содержит код, который может привести к возникновению исключительной ситуации.

• catch содержит код, который должен выполняться в случае возникновения исключительной ситуации. Блоки catch могут быть настроены таким образом, чтобы реагировать только на один конкретный тип исключительной ситуации (например, на System. IndexOutOfRangeException), для чего используется параметр <тилисключительнойСитуации>, поскольку существует возможность одновременно установить несколько блоков catch. Но можно и вообще опустить этот параметр, тогда получитсяобщий блок catch, который будет реагировать на все виды исключительных ситуаций.

• finally содержит блок кода, который выполняется всегда: либо после выполнения блока try, если не возникло никаких исключительных ситуаций, либо после блока catch, если производилась обработка исключительной ситуации, либо непосредственно перед тем, как

приложение будет завершено из-за возникновения необрабатываемой исключительной ситуации (последнее и объясняет необходимость этого блока; в противном случае мы могли бы с тем же успехом разместить этот код просто вслед за блоком).

События, происходящие после возникновения исключительной ситуации в блоке кода try, имеют такую последовательность:

• Выполнение блока try прекращается в той точке, в которой возникла исключительная ситуация.

• Если существует блок catch, то производится проверка на предмет того, совпадает ли его параметр с типом возникшей исключительной ситуации. Если блок catch отсутствует, то выполняется блок finally (который в этом случае является обязательным).

• Если блок catch существует, но значение его параметра не совпадает с типом возникшей исключительной ситуации, проверка производится в других блоках catch.

• Если параметр блока catch совпадает с типом возникшей исключительной ситуации, то сначала выполняется код, содержащийся в блоке, а затем — в случае, если он присутствует,— выполняется блок finally.

• Если ни один из блоков catch не соответствует типу возникшей исключительной ситуации, то выполняется блок finally (если он существует).

Рассмотрим пример, демонстрирующий, как отследить и перехватить исключение.

static void Main()

{

int x = int.Parse(Console.ReadLine());

int y =1 / x;

Console.WriteLine(y);

}

Перечислим, какие исключительные ситуации могут возникнуть:

  1. пользователь может ввести нечисловое значение

  2. если ввести значение 0, то произойдет деление на 0.

Создайте указанные исключительные ситуации и посмотрите, как отреагирует на них система.

Задание. Переменные x и y объявлены целочисленными. Объясните, что будет выведено на экран, если замените их тип на double и ввести с клавиатуры значение х равное 0, и почему.

Теперь попробуем обработать эти ситуации. Для этого изменим код следующим образом.

static void Main()

{

try

{

int x = int.Parse(Console.ReadLine());

int y =1 / x;

Console.WriteLine("y={0}", y);

Console.WriteLine("блок try выполнилсь успешно");

}

catch // *

{

Console.WriteLine("возникла какая-то ошибка");

}

Console.WriteLine("конец программы");

}

Рассмотрим, как обрабатываются исключения в данном примере. Когда возникает исключение, выполнение программы останавливается и управление передается блоку catch. Этот блок никогда не возвращает управление в то место программы, где возникло исключение. Поэтому команды из блока try, расположенные ниже строки, в которой возникло исключение, никогда не будут выполнены. Блок catch обрабатывает исключение, и выполнение программы продолжается с оператора, следующего за этим блоком.

В нашем случае при вводе нечислового значения или 0 будет выведено сообщение «возникла ошибка», а затем сообщение «конец программы».

Обработчик исключений позволяет не только отловить ошибку, но и вывести полную информацию о ней. Для демонстрации сказанного заменим блок catch следующим фрагментом.

catch (Exception error)

{

Console.WriteLine("Возникла ошибка {0}", error);

}

Теперь, если возникнет исключительная ситуация, «выброшенная» информация будет записана в идентификатор error. Данную информацию можно просмотреть с помощью метода WriteLine. Такое сообщение очень полное и будет полезно только разработчику на этапе отладки проекта.

Для пользователя на этапе эксплуатации приложения достаточно более краткой информации о типе ошибке. С этой целью в С# выделены стандартные классы исключений, такие как DivideByZeroException, FormatException.Внесем изменения в программу.

static void Main()

{

try

{

int x = int.Parse(Console.ReadLine()); // 1 ситуация

int y =1 / x; // 2 ситуация

Console.WriteLine("y={0}", y);

Console.WriteLine("блок try выполнилсь успешно");

}

catch(FormatException) // обработка 1 ситуации

{

Console.WriteLine("Ошибка: введено нечисловое значение!");

}

catch (DivideByZeroException) // обработка 2 ситуации

{

Console.WriteLine("Ошибка: деление на 0!");

}

Console.WriteLine("конец программы");

}

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

Имя

Описание

ArithmeticException

Ошибка в арифметических операциях или преобразованиях

ArrayTypeMismatchException

Попытка сохранения в массиве элемента несовместимого типа

DivideByZeroException

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

FormatException

Попытка передать в метод аргумент неверного формата

IndexOutOfRangeException

Индекс массива выходит за границу диапазона

InvalidCastException

Ошибка преобразования типа

OutOfMemoryException

Недостаточно памяти для нового объекта

OverflowException

Перевыполнение при выполнении арифметических операций

StackOverflowException

Переполнение стека

Одно из основных достоинств обработки исключений состоит в том, что она позволяет программе отреагировать на ошибку и продолжить выполнение. Рассмотрим программу, которая строит таблицу значений для функции вида .

staticvoidMain()

{

Console.WriteLine("a=");

int a = int.Parse( Console.ReadLine());

Console.WriteLine("b=");

int b = int.Parse(Console.ReadLine());

for (int i = a; i <= b; ++i)

{

try

{

Console.WriteLine("y({0})={1}", i, 100 / (i * i - 1));

}

catch (DivideByZeroException)

{

Console.WriteLine("y({0})=Деление на 0", i);

}

}

}

Если встречается деление на нуль, генерируется исключение типа DivideByZeroException. В программе это исключение обрабатывается выдачей сообщения об ошибке, после чего выполнение программы продолжается. При этом попытка разделить на нуль не вызывает внезапную динамическую ошибку (т.к. блок обработки прерываний помещен внутрь цикла for). Вместо этого исключение позволяет красиво выйти из ошибочной ситуации и продолжить выполнение программы.

Просмотр списков и настройка исключительных ситуаций

.NET Framework содержит огромное количество типов исключительных ситуаций, и мы обладаем полной свободой создавать и обрабатывать эти исключительные ситуации в своих программах и даже создавать исключительные ситуации для обработки более сложными приложениями. VS предоставляет специальный диалог (см. рис. внизу),позволяющий просматривать и редактировать имеющиеся исключительные ситуации, который можно вызвать через пункт менюDebug | Exceptions... (или нажатием комбинации клавишCtrl+Alt+E).

Соседние файлы в папке НПП_6_з_2013