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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 241 242 243 244 245 246 247 248 249 ... 642

После нажатия клавиши <ТаЬ> будет сгенерирован новый метод, как показано на рис. 12.2.

Обратите внимание, что код заглушки имеет корректный формат цели делегата (кроме того, метод объявлен как static, т.к. событие было зарегистрировано внутри статического метода):

static void NewCar_AboutToBlow(string msg)

{

  throw new NotImplementedException();

}

Средство IntelliSense доступно для всех событий .NET Core, ваших событий и событий из библиотек базовых классов.Такая возможность IDE-среды значительно экономит время, избавляя от необходимости выяснять с помощью справочной системы подходящий тип делегата для применения с заданным событием и формат целевого метода делегата.

Создание специальных аргументов событий

По правде говоря, в текущую итерацию класса Car можно было бы внести последнее усовершенствование, которое отражает рекомендованный Microsoft шаблон событий. Если вы начнете исследовать события, отправляемые определенным типом из библиотек базовых классов, то обнаружите, что первый параметр лежащего в основе делегата имеет тип System.Object, в то время как второй — тип, производный от System.EventArgs.

Параметр System.Object представляет ссылку на объект, который отправляет событие (такой как Car), а второй параметр — информацию, относящуюся к обрабатываемому событию. Базовый класс System.EventArgs представляет событие, которое не сопровождается какой-либо специальной информацией:

public class EventArgs

{

  public static readonly EventArgs Empty;

  public EventArgs();

}

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

using System;

namespace CarEvents

{

  public class CarEventArgs : EventArgs

  {

    public readonly string msg;

    public CarEventArgs(string message)

    {

      msg = message;

    }

(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})

  }

}

Теперь можно модифицировать тип делегата CarEngineHandler, как показано ниже (события не изменятся):

public class Car

{

  public delegate void CarEngineHandler(object sender, CarEventArgs e);

  ...

}

Здесь при инициировании событий внутри метода Accelerate() необходимо использовать ссылку на текущий объект Car (посредством ключевого слова this) и экземпляр типа CarEventArgs. Например, рассмотрим следующее обновление:

public void Accelerate(int delta)

{

  // Если этот автомобиль сломан, то инициировать событие Exploded.

  if (carIsDead)

  {

    Exploded?.Invoke(this, new CarEventArgs(&quot;Sorry, this car is dead...&quot;));

  }

  ...

}

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

static void CarAboutToBlow(object sender, CarEventArgs e)

{

  Console.WriteLine($&quot;{sender} says: {e.msg}&quot;);

}

Если получатель желает взаимодействовать с объектом, отправившим событие, тогда можно выполнить явное приведение System.Object. Такая ссылка позволит вызывать любой открытый метод объекта, который отправил уведомление:

static void CarAboutToBlow(object sender, CarEventArgs e)

{

  // Просто для подстраховки перед приведением

  // произвести проверку во время выполнения.

  if (sender is Car c)

  {

    Console.WriteLine(

      $&quot;Critical Message from {c.PetName}: {e.msg}&quot;);

  }

}

Обобщенный делегат EventHandler<T>

С учетом того, что очень многие специальные делегаты принимают экземпляр object в первом параметре и экземпляр производного от EventArgs класса во втором, предыдущий пример можно дополнительно упростить за счет применения обобщенного типа EventHandler&lt;T&gt;, где Т — специальный тип, производный от EventArgs. Рассмотрим следующую модификацию типа Car (обратите внимание, что определять специальный тип делегата больше не нужно):

1 ... 241 242 243 244 245 246 247 248 249 ... 642
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю бесплатно.
Похожие на Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю книги

Оставить комментарий