Шрифт:
public CarIsDeadException(string cause, DateTime time,
string message, System.Exception
inner) :
base(message, inner)
{
CauseOfError = cause;
ErrorTimeStamp = time;
}
}
Затем необходимо модифицировать метод
Accelerate
с учетом обновленного специального исключения:
throw new CarIsDeadException("You have a lead foot",
DateTime.Now,$"{PetName} has overheated!")
{
HelpLink = "http://www.CarsRUs.com",
};
Поскольку создаваемые специальные исключения, следующие установившейся практике в .NET Core, на самом деле отличаются только своими именами, полезно знать, что среды Visual Studio и Visual Studio Code предлагает фрагмент кода, который автоматически генерирует новый класс исключения, отвечающий рекомендациям .NET. Для его активизации наберите
ехс
и нажмите клавишу <ТаЬ> (в Visual Studio нажмите <Tab> два раза). Обработка множества исключений
В своей простейшей форме блок
try
сопровождается единственным блоком catch
. Однако в реальности часто приходится сталкиваться с ситуациями, когда операторы внутри блока try
могут генерировать многочисленные исключения. Создайте новый проект консольного приложения на C# по имени ProcessMultipleExpceptions
, скопируйте в него файлы Car.cs
, Radio.cs
и CarIsDeadException.cs
из предыдущего проекта CustomException
и надлежащим образом измените название пространства имен. Затем модифицируйте метод
Accelerate
класса Car
так, чтобы он генерировал еще и предопределенное в библиотеках базовых классов исключение ArgumentOutOfRangeException
, если передается недопустимый параметр (которым будет считаться любое значение меньше нуля). Обратите внимание, что конструктор этого класса исключения принимает имя проблемного аргумента в первом параметре типа string
, за которым следует сообщение с описанием ошибки.
// Перед продолжением проверить аргумент на предмет допустимости.
public void Accelerate(int delta)
{
if (delta < 0)
{
throw new ArgumentOutOfRangeException(nameof(delta),
"Speed must be greater than zero");
// Значение скорости должно быть больше нуля!
}
...
}
На заметку! Операция
nameof
возвращает строку, представляющую имя объекта, т.е. переменную delta
в рассматриваемом примере. Такой прием позволяет безопасно ссылаться на объекты, методы и переменные С#, когда требуются их строковые версии. Теперь логика в блоке
catch
может реагировать на каждый тип исключения специфическим образом:
using System;
using System.IO;
using ProcessMultipleExceptions;
Console.WriteLine("***** Handling Multiple Exceptions *****\n");
Car myCar = new Car("Rusty", 90);
try
{
// Вызвать исключение выхода за пределы диапазона аргумента.
myCar.Accelerate(-10);
}
catch (CarIsDeadException e)
{
Console.WriteLine(e.Message);
}
catch (ArgumentOutOfRangeException e)
{
Console.WriteLine(e.Message);
}
Console.ReadLine;
При написании множества блоков
catch
вы должны иметь в виду, что когда исключение сгенерировано, оно будет обрабатываться первым подходящим блоком catch
. Чтобы проиллюстрировать, что означает "первый подходящий" блок catch
, модифицируйте предыдущий код, добавив еще один блок catch
, который пытается обработать все остальные исключения кроме CarIsDeadException
и ArgumentOutOfRangeException
путем перехвата общего типа System.Exception
:
// Этот код не скомпилируется!
Console.WriteLine("***** Handling Multiple Exceptions *****\n");
Car myCar = new Car("Rusty", 90);
try
{
// Вызвать исключение выхода за пределы диапазона аргумента.
myCar.Accelerate(-10);
}
catch(Exception e)
{
// Обработать все остальные исключения?