Обработка исключительных ситуаций 2

advertisement
26) Листинг 13.12
// Использовать члены класса Exception.
using System;
class ExcTest
{
public static void GenException()
{
int[] nums = new int[4];
Console.WriteLine("До генерирования исключения.");
// Сгенерировать исключение в связи с выходом за границы
массива.
for(int i=0; i < 10; i++) {
nums[i] = i;
Console.WriteLine("nums[{0}]: {1}", i, nums[i]);
}
Console.WriteLine("Не подлежит выводу");
}
}
class UseExcept
{
static void Main()
{
try {
ExcTest.GenException();
}
catch (IndexOutOfRangeException exc)
{
Console.WriteLine("Стандартное сообщение: ");
Console.WriteLine(exc); // вызвать метод ToString()
Console.WriteLine("Свойство
StackTrace:
"
+
exc.StackTrace);
Console.WriteLine("Свойство
Message:
"
+
exc.Message);
Console.WriteLine("Свойство
TargetSite:
"
+
exc.TargetSite);
}
Console.WriteLine("После блока перехвата исключения.");
}
}
До генерирования исключения.
nums[0]: 0
nums[1]: 1
nums[2]: 2
nums[3]: 3
Стандартное сообщение таково:
System.IndexOutOfRangeException: Индекс находился вне
границ массива.
в ExcTest.genException() в <имя_файла>:строка 15
в UseExcept.Main()в <имя_файла>:строка 29
Свойство
StackTrace:
в
ExcTest.genException()в
<имя_файла>:строка 15
в UseExcept.Main()B <имя_файла>:строка 29
Свойство Message: Индекс находился вне границ массива.
Свойство TargetSite: Void genException()
После блока перехвата исключения.
28)
public Exception ()
public Exception(string сообщение)
public Exception(string сообщение,
Exception внутреннее_исключение)
protected
Exception(System.Runtime.Serialization.
SerializationInfо информация,
System.Runtime.Serialization.StreamingContext
контекст)
Исключение
ArrayTypeMismatchException
DivideByZeroException
IndexOutOfRangeException
InvalidCastException
OutOfMemoryExceprion
OverflowException
NullReferenceException
Значение
Тип сохраняемого значения несовместим с типом
массива
Попытка деления на нуль
Индекс оказался за границами массива
Неверно выполнено динамическое приведение типов
Недостаточно свободной памяти для дальнейшего
выполнения программы. Это исключение может быть,
например, сгенерировано, если для создания объекта
с помощью оператора new не хватает памяти
Произошло арифметическое переполнение
Попытка использовать пустую ссылку, т. е. ссылку,
которая не указывает ни на один из объектов
30) Листинг 13.13
//
Продемонстрировать
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);
}
}
31)
Исключение NullReferenceException!
Исправление ошибки...
Значение val равно 19
32)
Листинг 13.14
// Использовать специальное исключение для обработки
// ошибок при обращении к массиву класса RangeArray.
using System;
// Создать исключение для класса RangeArray.
class RangeArrayException : Exception
{
/* Реализовать все конструкторы класса Exception.
Такие конструкторы просто реализуют
конструктор базового класса. А поскольку
класс исключения RangeArrayException ничего
не добавляет к классу Exception, то никаких
дополнительных действий не требуется */
public RangeArrayException() : base() { }
public
RangeArrayException(string
message)
base(message) { }
:
public RangeArrayException(string message,
Exception innerException) :
base(message, innerException) { }
protected RangeArrayException
{
System.Runtime.Serialization.SerializationInfo
info,
System.Runtime.Serialization.StreamingContext
context):
base(info, context) { }
// Переопределить метод ToString()
// для класса исключения RangeArrayException.
public override string ToString()
{
return Message;
}
}
// Улучшенный вариант класса RangeArray.
class RangeArray {
// Private data.
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;
upperBound = --high;
}
// Этот индексатор для класса RangeArray.
public int this[int index] {
// Это аксессор get.
get {
if(ok(index)) {
return a[index - lowerBound];
} else {
throw
new
RangeArrayException("Ошибка
нарушения границ.");
}
}
// Это аксессор set.
set {
if(ok(index)) {
a[index - lowerBound] = value;
else
throw
new
RangeArrayException("Ошибка
нарушения границ.");
}
}
// Возвратить логическое значение true, если
// индекс находится в установленных границах.
private bool ok(int index)
{
if(index >= lowerBound & index <= upperBound)
return true;
return false;
}
}
// Продемонстрировать применение массива с
произвольно
// задаваемыми пределами индексирования.
class RangeArrayDemo
{
static void Main()
{
try {
RangeArray ra = new RangeArray(-5, 5);
RangeArray ra2 = new RangeArray(1, 10);
// Использовать объект ra в качестве массива.
Console.WriteLine("Длина массива ra: " +
ra.Length);
for(int i = -5; i <= 5; i++)
ra[i] = i;
Console.Write("Содержимое массива ra: ");
for(int i = -5; i <= 5; i++)
Console.Write(ra[i] + " ");
Console.WriteLine("\n");
// Использовать объект ra2 в качестве массива.
Console.WriteLine("Длина массива ra2: " +
ra2.Length);
for(int i = 1; i <= 10; i++)
ra2[i] = i;
Console.Write("Содержимое массива ra2: ");
for(int i = 1; i <= 10; i++)
Console.Write(ra2[i] + " ");
Console.WriteLine("\n");
} catch (RangeArrayException exc) {
Console.WriteLine(exc);
}
// А теперь продемонстрировать обработку
некоторых ошибок.
Console.WriteLine("Сгенерировать ошибки нарушения
границ.");
// Использовать неверно заданный индекс.
try {
RangeArray ra3 = new RangeArray(100, -10); //
Error
} catch (RangeArrayException exc) {
Console.WriteLine(exc);
}
// Use an invalid index.
try
for(int i = -2; i <= 2; i++)
ra3[i] = i;
Console.Write("Содержимое массива ra3: ");
for(int i = -2; i <= 10; i++) // Сгенерировать
ошибку
// нарушения границ
Console.Write(ra3[i] + " ");
} catch (RangeArrayException exc) {
Console.WriteLine(exc);
}
}
}
33)
Длина массива rа: 11
Содержимое массива rа: -5-4-3-2-1 0 1 2 3 4 5
Длина массива rа2: 10
Содержимое массива ra2:
1 2 3 4 5 6 7 8 9 10
Сгенерировать ошибки нарушения границ.
Нижний индекс не меньше верхнего.
Содержимое массива rа3: -2-1012 Ошибка нарушения
границ.
34) Листинг 13.15
// Исключения производных классов должны появляться до
// исключения базового класса.
using System;
// Создать класс исключения.
class ExceptA : Exception
{
public ExceptA(string message) : base(message) { }
public override string ToString()
{
return Message;
}
}
// Создать класс исключения, производный от класса
ExceptA
class ExceptB : ExceptA
{
public ExceptB(string message) : base(message) { }
public override string ToString() {
return Message;
}
}
class OrderMatters
{
static void Main()
{
for(int x = 0; x < 3; x++) {
try {
if(x==0)
throw new ExceptA("Перехват исключения типа
ExceptA");
else if(x==1)
throw new ExceptB("Перехват исключения типа
ExceptB");
catch (ExceptB exc) {
Console.WriteLine(exc);
}
catch (ExceptA exc) {
Console.WriteLine(exc);
}
catch (Exception exc) {
Console.WriteLine(exc);
}
}
}
}
35)
Перехват исключения типа ExceptA.
Перехват исключения типа ExceptB.
System.Exception:
Выдано исключение типа
"System.Exception".
в OrderMatters.Main() в <имя_файла>:строка 36
36)
byte а, b, result;
а = 127; b = 127;
result = (byte)(а * b);
checked (выражение)
37)
checked
{
// проверяемые операторы
}
unchecked (выражение)
38)
unchecked
{
// операторы, для которых переполнение игнорируется
}
39) Листинг 13.16
// Продемонстрировать применение ключевых слов checked
и unchecked.
using System;
class CheckedDemo
{
static void Main()
{
byte a, b;
byte result;
a = 127;
b = 127;
try {
result = unchecked((byte)(a * b));
Console.WriteLine("Непроверенный на переполнение
результат: " +
result);
result = checked((byte)(a * b));
// эта операция приводит к
// исключительной ситуации
Console.WriteLine("Проверенный на переполнение
результат: " +
result);
// не подлежит
выполнению
}
catch (OverflowException exc)
{
Console.WriteLine(exc);
}
}
}
40)
Непроверенный на переполнение результат: 1
System.OverflowException: Переполнение в результате
выполнения арифметической операции.
в CheckedDemo.Main() в <имя_файла>:строка 20
41) Листинг 13.17
// Продемонстрировать применение ключевых слов checked
// и unchecked в блоке операторов.
using System;
class CheckedBlocks
{
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("Непроверенный на
переполнение результат: " +
result);
a = 125;
b = 5;
result = unchecked((byte)(a * b));
Console.WriteLine("Непроверенный на
переполнение результат: " +
result);
}
checked
{
a = 2;
b = 7;
result = checked((byte)(a * b)); // правильно
Console.WriteLine("Проверенный на переполнение
результат: " +
result);
a = 127;
result = checked((byte)(a * b)); // эта операция
приводит к
// исключительной ситуации
Console.WriteLine("Проверенный на переполнение
результат: " +
result); // не подлежит выполнению
}
}
catch (OverflowException exc)
{
Console.WriteLine(exc);
}
}
}
42)Непроверенный на переполнение результат: 1
Непроверенный на переполнение результат: 113
Проверенный на переполнение результат: 14
System.OverflowException: Переполнение в результате
выполнения арифметической операции.
в CheckedDemo.Main() в <имя_файла>:строка 41
Download
Study collections