Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Генерация исключений






Об обработке исключений, посылаемых методами библиотечных классов, мы уже говорили и неоднократно пользовались. Чтобы глубже разобраться в механизме генерации исключений и научиться создавать и посылать исключения в любой заранее предусмотренной ситуации, возникшей при выполнении программы, нужно ясно понять и усвоить, что исключения – это объекты некоторых специальных классов. Все системные классы исключений являются производными от класса System.Exception. Этот класс имеет несколько замечательных свойств, два из которых (Message и Sourse) мы уже применяли. При создании объектов классов исключений наиболее важными являются Message и InnerException. Оба эти свойства в обязательном порядке используются всеми исключениями. Оба свойства предназначены только для чтения.

Message – это свойство типа String, значение которого представляет собой текст сообщения о причине возникновения исключения.

InnerException – имеет тип Exception и представляет собой ненулевую ссылку на то исключение, которое является причиной возникновения данного исключения.

Значения этих свойств можно задать с помощью параметров конструктора при создании объекта класса System.Exception. Нам могут быть полезны следующие конструкторы:

Exception() – инициализирует умалчиваемыми данными новый экземпляр класса Exception.

Exception(String) – инициализирует новое исключение (новый объект). Параметр задаёт значение свойства Message.

Exception(String, Exception) – параметр типа String определяет значение свойства Message, а второй параметр представляет собой ссылку на внутреннее исключение, которое явилось причиной данного исключения.

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

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

throw выражение;

throw;

Оператор throw без выражения; можно использовать только в catch-блоке для ретрансляции исключения в catch-блок следующего уровня.

Значением выражения, использованного в операторе throw, должна быть ссылка на объект класса исключений. Именно этот объект посылается в качестве исключения. Если значение выражения равно null, то вместо него посылается исключение System.NullReference.Exception.

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

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

Ошибки ввода в данном случае могут быть двух видов – лексические и семантические. Лексическая ошибка - это неверная запись вещественного числа при его наборе на клавиатуре. Семантическая ошибка – отличие введённого числа от трёх допустимых условием задачи значений (110, 127, 220). Для преобразования введённой с клавиатуры последовательности символов в числовое значение применим метод TryParse(). Тогда послать исключение при лексической ошибке можно с помощью следующих операторов:

string input = Console.ReadLine();

if (! double.TryParse(input, out U))

throw new Exception(" Ошибка в формате данных! ");

В данном фрагменте U – имя переменной типа double, которая будет представлять в программе введённое пользователем значение напряжения.

Для генерации исключения при семантической ошибки используем такой код:

if (U! = 110 & U! = 127 & U! = 220)

throw new Exception(input+" - недопустимое значение! ");

Все приведённые операторы разместим в try-блоке, вслед за которым поместим обработчик исключений (catch-блок), где будем подсчитывать их количество. Всю конструкцию try/catch поместим в цикл. Тем, кто забыл раздел физики, посвященный электричеству, напомним, что мощность, потребляемая сопротивлением R при его включении в сеть с напряжением U, вычисляется по формуле U2/R- Программа в целом может быть такой:

// 16_05.cs - исключения для проверки вводимых данных

public static void Main05()

{

double U, R=100;

int counter = 0; // Счетчик исключений

while (true)

{ Console.Write(" Введите напряжение (110, 127, 220): ");

try

{

string input = Console.ReadLine();

if (! double.TryParse(input, out U))

throw new Exception(" Ошибка в формате данных! ");

if (U! = 110 & U! = 127 & U! = 220)

throw new Exception(input+" - недопустимое значение! ");

}

catch (Exception ex)

{

Console.WriteLine(ex. Message);

if (counter++ > = 2)

{ Console.WriteLine(" Трижды ошиблись! ");

return;

}

continue;

}

break;

} // end of while

Console.WriteLine(" Потребляемая мощность: {0, 5: f2}", U * U / R);

}

Результат выполнения программы:

* Первый сеанс:

Введите напряжение (110, 127, 220): 120< ENTER>

120 - недопустимое значение!

Введите напряжение (110, 127, 220): 110f< ENTER>

Ошибка в формате данных!

Введите напряжение (110, 127, 220): asd< ENTER>

Ошибка в формате данных!

Трижды ошиблись!

* Второй сеанс:

Введите напряжение (110, 127, 220): 127< ENTER> Потребляемая мощность: 161, 29

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

При обращении к методу могут быть по ошибке использованы аргументы, представляющие массивы с разным количеством элементов. Предусмотрим защиту от такой ошибки, посылая исключение в случае неравенства размеров массивов-аргументов. Тогда первые строки кода метода могут быть такими:

static double scalar(double[] x, double[] y)

{

if (x.Length! = y.Length)

throw new Exception(" Неверные размеры векторов! ");

}

Обработку исключений, формируемых методом при ошибке в его аргументах, обычно выполняют в коде, из которого выполнено обращение к методу. (Там, где заданы конкретные аргументы.) В следующей программе обращения к методу scalar() размещены в try-блоке. Первое обращение корректно, во втором допущена ошибка - размеры массивов-аргументов не совпадают. Текст программы:

// 16_06.cs - исключения в теле метода

static double scalar(double[] x, double[] y)

{

if (x.Length! = y.Length)

throw new Exception(" Неверные размеры векторов! ");

double result = 0;

for (int i = 0; i < x.Length; i++)

result += x[i] * y[i];

return Math.Sqrt(result);

}

public static void Main06()

{

try

{

Console.WriteLine(" scalar1=" + scalar(new double[] {1, 2, 3, 4}, new double[] {1, 2, 3, 4}));

Console.WriteLine(" scalar2=" +scalar(new double[] {1, 2, 3, 4}, new double[] {1, 2, 3}));

}

catch (Exception ex)

{

Console.WriteLine(ex.Message);

}

}

Результат выполнения программы:

scalar1 = 5, 47722557505166
Неверные размеры векторов!






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.