Хотя свойства TargetSite и StackTrace позволяют программистам выяснить, почему возникло конкретное исключение, информация подобного рода не особенно полезна для пользователей. Как уже было показано, с помощью свойства System.Exception. Message можно извлечь читабельную информацию и отобразить ее конечному пользователю. Вдобавок можно установить свойство HelpLink для указания на специальный URL или стандартный справочный файл, где приводятся более подробные сведения о проблеме.
По умолчанию значением свойства HelpLink является пустая строка. Обновите исключение с использованием инициализации объектов, чтобы предоставить более интересное значение. Ниже показан модифицированный код метода Car.Accelerate:
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!")
{
HelpLink = "http://www.CarsRUs.com"
};
}
Console.WriteLine("=> CurrentSpeed = {0}", CurrentSpeed);
}
}
Теперь можно обновить логику в блоке catch для вывода на консоль информации из свойства HelpLink:
catch(Exception e)
{
...
Console.WriteLine("Help Link: {0}", e.HelpLink);
}
Свойство Data
Свойство Data класса System.Exception позволяет заполнить объект исключения подходящей вспомогательной информацией (такой как отметка времени). Свойство Data возвращает объект, который реализует интерфейс по имени IDictionary, определенный в пространстве имен System.Collections. В главе 8 исследуется роль программирования на основе интерфейсов, а также рассматривается пространство имен System.Collections. В текущий момент важно понимать лишь то, что словарные коллекции позволяют создавать наборы значений, извлекаемых по ключу. Взгляните на очередное изменение метода Car.Accelerate:
public void Accelerate(int delta)
{
if (_carIsDead)
{
Console.WriteLine("{0} is out of order...", PetName);
}
else
{
CurrentSpeed += delta;
if (CurrentSpeed >= MaxSpeed)
{
Console.WriteLine("{0} has overheated!", PetName);
CurrentSpeed = 0;
_carIsDead = true;
// Использовать ключевое слово throw для генерации
// исключения и возврата в вызывающий код.
throw new Exception($"{PetName} has overheated!")
{
HelpLink = "http://www.CarsRUs.com",
Data = {
{"TimeStamp",$"The car exploded at {DateTime.Now}"},
{"Cause","You have a lead foot."}
}
};
}
Console.WriteLine("=> CurrentSpeed = {0}", CurrentSpeed);
}
}
С целью успешного прохода по парам "ключ-значение" добавьте директиву using для пространства имен System.Collections, т.к. в файле с операторами верхнего уровня будет применяться тип DictionaryEntry:
using System.Collections;
Затем обновите логику в блоке catch, чтобы обеспечить проверку значения, возвращаемого из свойства Data, на равенство null (т.е. стандартному значению). После этого свойства Key и Value типа DictionaryEntry используются для вывода специальных данных на консоль:
catch (Exception e)
{
...
Console.WriteLine("\n-> Custom Data:");
foreach (DictionaryEntry de in e.Data)
{
Console.WriteLine("-> {0}: {1}", de.Key, de.Value);
}
}
Вот как теперь выглядит финальный вывод программы:
***** Simple Exception Example *****
=> Creating a car and stepping on it!
Jamming...
=> CurrentSpeed = 30
=> CurrentSpeed = 40
=> CurrentSpeed = 50
=> CurrentSpeed = 60