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

Domnin_Lab_9-12 / ЛАБ_12_C# / ИСКЛЮЧИТЕЛЬНЫЕ СИТУАЦИИ И ИХ ОБРАБОТКА

.doc
Скачиваний:
16
Добавлен:
02.02.2015
Размер:
335.36 Кб
Скачать

// Демонстрируем использование объекта-массива ra2. 90

Console.WriteLine(" Длинна массива ra2 -6 ( 91 ) : " + ra2.Length);

for(int i = 1; i <= 10; i++)

ra2[i] = i;

Console.Write(" Содержимое массива ra2 -7 ( >90 ) : ");

for(int i = 1; i <= 10; i++)

Console.Write(ra2[i] + " ");

Console.WriteLine("\n");

} catch(RangeArrayException exc) {

Console.WriteLine(exc);

}

// Теперь демонстрируем "работу над ошибками"

Console.WriteLine(" Сгенерируем ошибки непопадания в диапазон -8(<107)" );

// Используем неверно заданный конструктор. 107

try {

RangeArray ra3 = new RangeArray (100, -10); // Ошибка!

} catch ( RangeArrayException exc) {

Console.WriteLine(exc);

}

// Используем неверно заданный индекс 115

try {

RangeArray ra3 = new RangeArray(-2, 2);

for(int i = -2; i <= 2; i++)

ra3[i] = i;

Console.Write("\n Cодержимое массива ra3 -9 ( 122 ) : ");

for(int i = -2; i <= 10; i++) // Ошибка непопадание в диапазон 123

Console.Write(ra3[i] + " ");

} catch(RangeArrayException exc) {

Console.WriteLine(exc);

}

Console.WriteLine("\n\n\n ");

}

}

Рис 9.1 Результаты наследования исключений, созданных пользователями

Рис 9.2 Результаты переопределения (закомментирования) метода ToString().

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

При перехвате исключений базовых и производных классов следует иметь в виду, что catch-инструкции базовых классов всегда перехватываю все инструкции производных классов. Поэтому при необходимости фиксации всех исключений всегда следует вначале перехватывать исключения производных классов и выполнять их необходимую обработку, а только в конце обрабатывать исключения базовых классов.

10

// В начале перехватываются исключения производных классов, а потом базовых

using System;

// Создаем класс исключения

class ExcA : ApplicationException {

public ExcA() : base() {}

public ExcA(string str) : base(str) { }

public override string ToString() {

return Message;

}

}

// Cоздаем класс исключения как производный от класса ExcA. 14

class ExcB : ExcA {

public ExcB() : base() { }

public ExcB(string str) : base(str) { }

public override string ToString() {

return Message;

}

}

class OrderMatters {

public static void Main() {

Console.WriteLine(" ");

for(int x=0; x <3; x++) {

try {

if(x==0) throw new ExcA(" Перехват исключение типа ExcA.");

else if(x==1)throw new ExcB(" Перехват исключения типа ExcB.");

else throw new Exception();

}

catch (ExcB exc) {

// Перехватываем исключение 34

Console.WriteLine(exc);

}

catch(ExcA exc) {

// Перехватываем исключение 38

Console.WriteLine(exc);

}

catch(Exception exc) {

Console.WriteLine(exc);

}

}

Console.WriteLine("\n\n\n ");

}

}

Рис 10 Порядок выполнения производных и базовых исключений

Из текста программы следует, что наибольшим приоритетом обработки обладают исключения класса Application Exception, из него выхлдит класс ExcA и самым низким приоритетом обладает класс ExcB. Поэтому в тексте программы приведено единственно верное размещение catch-блоков, при котором все имеющиеся исключения перехватываются. Любое другое размещение порядка срабатывания catch-блоков приведет к пропуску обработки исключений.

Работа с ключевыми словами checked и unchecked

checked – проверенный, unchecked - непроверенный

Данные слова применяются для управления переполнением в результатевыполнения арифметических выражений. Имеют по две формы каждое. Так одна операторная checked-форма – checked ( expr).

Другая проверяет блок иструкций: сhecked {

// Инструкии, подлежащие проверке

}

здесь : expr – контролизуемое выражение

При переполнении генерируется исключение тпа OverflowException.

Две форы для unchecked. Одна – операторная форма, игнорирует переполнение для заданного выражения. Вторая – в блоке инструкций игнорирует переполнение.

unchecked (expr) unchecked {

переполнение игнорируется // Инструкции, для которых переполнение

// игнорируется

}

Здесь: expr – выражение не проверяется на переполнение.

11

// Работа с checked и unchecked

using System;

class checkedD {

public static void Main() {

byte a, b;

byte result;

a = 127;

b = 127;

try {

result = unchecked ((byte)(a * b));

Console.WriteLine("\n Unchecked-результат: " + result);

result = checked((byte)( a* b )); // Это инструкция вызывает исключение

Console.WriteLine(" checked- результат" +

result); // Инструкция не будет выполненна.

}

catch (OverflowException exc) {

// Перехватываем исключение.

Console.WriteLine(exc);

}

Console.WriteLine ( "\n\n\n " );

}

}

Рис 11 Результат непроверяемого выражения усекается

Использование ключевых слов для блоков инструкций

12

// Работа с checked и unchecked для блоков инструкций

using System;

class CheckedBlocks

{

public static void Main()

{

byte a, b;

byte result;

a = 127;

b = 127;

try

{

unchecked

{

a = 127;

b = 127;

result = unchecked((byte)(a * b));

Console.WriteLine("\n Unchecked-результат: " + result);

a = 125;

b = 5;

result = unchecked((byte)(a * b));

Console.WriteLine(" Unchecked-результат: " + result);

}

checked

{

a = 2;

b = 7;

result = checked((byte)(a * b)); // Все в порядке

Console.WriteLine(" checked-результат: " + result);

a = 127;

b = 127;

result = checked((byte)(a * b)); // Здесь должно быть

// сгенеррованно исключение

Console.WriteLine(" checked-результат: " + result);

// Эта инструкция не выполнится

}

}

catch (OverflowException exc)

{

// Перехватываем исключение.

Console.WriteLine(exc);

}

Console.WriteLine("\n\n\n ");

}

}

Рис 12 Использование ключевых слов для блоков с инструкцией

Опции checked/ unchecked могут быть опциями компилятора и тогда есть смысл в программах пользователя задавать статус контроля переполнения.

22