Книги онлайн и без регистрации » Разная литература » Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен

Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 98 99 100 101 102 103 104 105 106 ... 407
Перейти на страницу:
быть, с несколько меньшим объемом функциональности, например, без возможности взаимодействия с удаленным источником данных).

Выражение throw (нововведение в версии 7.0)

 До выхода версии C# 7 ключевое слово throw было оператором, что означало возможность генерации исключения только там, где разрешены операторы. В C# 7.0 и последующих версиях ключевое слово throw доступно также в виде выражения и может использоваться везде, где разрешены выражения.

Конфигурирование состояния исключения

В настоящий момент объект System.Exception, сконфигурированный внутри метода Accelerate(), просто устанавливает значение, доступное через свойство Message (посредством параметра конструктора). Как было показано ранее в табл. 7.1, класс Exception также предлагает несколько дополнительных членов (TargetSite, StackTrace, HelpLink и Data), которые полезны для дальнейшего уточнения природы возникшей проблемы. Чтобы усовершенствовать текущий пример, давайте по очереди рассмотрим возможности упомянутых членов.

Свойство TargetSite

Свойство System.Exception.TargetSite позволяет выяснить разнообразные детали о методе, который сгенерировал заданное исключение. Как демонстрировалось в предыдущем примере кода, в результате вывода значения свойства TargetSite отобразится возвращаемое значение, имя и типы параметров метода, который сгенерировал исключение. Однако свойство TargetSite возвращает не простую строку, а строго типизированный объект System.Reflection.MethodBase. Данный тип можно применять для сбора многочисленных деталей, касающихся проблемного метода, а также класса, в котором метод определен. В целях иллюстрации измените предыдущую логику в блоке catch следующим образом:

// Свойство TargetSite в действительности возвращает объект MethodBase.

catch(Exception e)

{

  Console.WriteLine("n*** Error! ***");

  Console.WriteLine("Member name: {0}", e.TargetSite);  // имя члена

  Console.WriteLine("Class defining member: {0}",

    e.TargetSite.DeclaringType);               // класс, определяющий член

  Console.WriteLine("Member type: {0}",

    e.TargetSite.MemberType);

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

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

}

Console.WriteLine("n***** Out of exception logic *****");

Console.ReadLine();

На этот раз в коде используется свойство MethodBase.DeclaringType для выяснения полностью заданного имени класса, сгенерировавшего ошибку (в данном случае SimpleException.Car), а также свойство MemberType объекта MethodBase для идентификации вида члена (например, член является свойством или методом), в котором возникло исключение. Ниже показано, как будет выглядеть вывод в результате выполнения логики в блоке catch:

*** Error! ***

Member name: Void Accelerate(Int32)

Class defining member: SimpleException.Car

Member type: Method

Message: Zippy has overheated!

Source: SimpleException

Свойство StackTrace

Свойство System.Exception.StackTrace позволяет идентифицировать последовательность вызовов, которая в результате привела к генерации исключения. Значение данного свойства никогда не устанавливается вручную — это делается автоматически во время создания объекта исключения. Чтобы удостовериться в сказанном, модифицируйте логику в блоке catch:

catch(Exception e)

{

  ...

  Console.WriteLine("Stack: {0}", e.StackTrace);

}

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

Stack: at SimpleException.Car.Accelerate(Int32 delta)

in [путь к файлу]car.cs:line 57 at <Program>$.<Main>$(String[] args)

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

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

Свойство HelpLink

Хотя свойства 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}"},

         

1 ... 98 99 100 101 102 103 104 105 106 ... 407
Перейти на страницу:

Комментарии
Минимальная длина комментария - 20 знаков. В коментария нецензурная лексика и оскорбления ЗАПРЕЩЕНЫ! Уважайте себя и других!
Комментариев еще нет. Хотите быть первым?