Чтение онлайн

ЖАНРЫ

Язык программирования C#9 и платформа .NET5
Шрифт:

Jamming...

=> CurrentSpeed = 30

=> CurrentSpeed = 40

=> CurrentSpeed = 50

=> CurrentSpeed = 60

=> CurrentSpeed = 70

=> CurrentSpeed = 80

=> CurrentSpeed = 90

=> CurrentSpeed = 100

Zippy has overheated!

Zippy is out of order...

Генерация общего исключения

Теперь, имея функциональный класс

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

Чтобы модернизировать метод

Accelerate
для генерации исключения, когда пользователь пытается разогнать автомобиль до скорости, которая превышает установленный предел, потребуется создать и сконфигурировать новый экземпляр класса
System.Exception
, установив значение доступного только для чтения свойства
Message
через конструктор класса. Для отправки объекта ошибки обратно вызывающему коду применяется ключевое слово
throw
языка С#. Ниже приведен обновленный код метода
Accelerate
:

// На этот раз генерировать исключение, если пользователь

// превышает предел, указанный в MaxSpeed.

public void Accelerate(int delta)

{

if (_carIsDead)

{

Console.WriteLine("{0} is out of order...", PetName);

}

else

{

CurrentSpeed += delta;

if (CurrentSpeed >= MaxSpeed)

{

CurrentSpeed = 0;

_carIsDead = true;

// Использовать ключевое слово throw для генерации исключения.

throw new Exception($"{PetName} has overheated!");

}

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

}

}

Прежде чем выяснять, каким образом вызывающий код будет перехватывать данное исключение, необходимо отметить несколько интересных моментов. Для начала, если вы генерируете исключение, то всегда самостоятельно решаете, как вводится в действие ошибка и когда должно генерироваться исключение. Здесь мы предполагаем, что при попытке увеличить скорость объекта

Car
за пределы максимума должен быть сгенерирован объект
System.Exception
для уведомления о невозможности продолжить выполнение метода
Accelerate
(в зависимости от создаваемого приложения такое предположение может быть как допустимым, так и нет).

В качестве альтернативы метод

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

Кроме того, обратите внимание, что из кода метода был удален финальный оператор

else
. Когда исключение генерируется (либо инфраструктурой, либо вручную с применением оператора
throw
), управление возвращается вызывающему методу (или блоку
catch
в операторе
try
). Это устраняет необходимость в финальном
else
. Оставите вы его ради лучшей читабельности или нет, зависит от ваших стандартов написания кода.

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

***** Simple Exception Example *****

=> Creating a car and stepping on it!

Jamming...

=> CurrentSpeed = 30

=> CurrentSpeed = 40

=> CurrentSpeed = 50

=> CurrentSpeed = 60

=> CurrentSpeed = 70

=> CurrentSpeed = 80

=> CurrentSpeed = 90

=> CurrentSpeed = 100

Unhandled exception. System.Exception: Zippy has overheated!

at SimpleException.Car.Accelerate(Int32 delta)

in [путь к файлу]\Car.cs:line 52

at SimpleException.Program.Main(String[] args)

in [путь к файлу]\Program.cs:line 16

Перехват исключений

На заметку! Те, кто пришел в .NET 5 из мира Java, должны помнить о том, что члены типа не прототипируются набором исключений, которые они могут генерировать (другими словами, платформа .NET Core не поддерживает проверяемые исключения). Лучше это или хуже, но вы не обязаны обрабатывать каждое исключение, генерируемое отдельно взятым членом.

Поскольку метод

Accelerate
теперь генерирует исключение, вызывающий код должен быть готов обработать его, если оно возникнет. При вызове метода, который может сгенерировать исключение, должен использоваться блок
try/catch
. После перехвата объекта исключения можно обращаться к различным его членам и извлекать детальную информацию о проблеме.

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

// Обработка сгенерированного исключения.

Console.WriteLine("***** Simple Exception Example *****");

Console.WriteLine("=> Creating a car and stepping on it!");

Car myCar = new Car("Zippy", 20);

myCar.CrankTunes(true);

// Разогнаться до скорости, превышающей максимальный

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

try

{

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

{

myCar. Accelerate(10);

}

}

catch(Exception e)

{

Console.WriteLine("\n*** Error! ***"); // ошибка

Console.WriteLine("Method: {0}", e.TargetSite); // метод

Console.WriteLine("Message: {0}", e.Message); // сообщение

Console.WriteLine("Source: {0}", e.Source); // источник

Поделиться с друзьями: