Книга: ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание

"Разборчивые" события

"Разборчивые" события

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

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

public class EventArgs {
 public static readonly System.EventArgs Empty;
 public EventArgs();
}

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

public class CarEventArgs: EventArgs {
 public readonly string msg;
 public CarEventArgs(string message) {
  msg = message;
 }
}

Теперь мы должны обновить делегат CarEventHandler так, как показано ниже (события должны остаться без изменений).

public class Car {
 public delegate void CarEventHandler(object sender, CarEventArgs e);
 …
}

При генерировании событий из метода Accelerate() мы теперь должны предоставить ссылку на текущий объект Car (с помощью ключевого слова Car) и экземпляр нашего типа CarEventArgs.

public void Accelerate(int delta) {
 // Если машина сломалась, генерируется событие Exploded.
 if (carIsDead) {
  if (Exploded != null) Exploded(this, new CarEventArgs("Извините, машина сломалась…"));
  else {
   …
   AboutToBlow(this, new CarEventArgs("Осторожно! Могу сломаться!"));
  }
  …
 }
}

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

public static void CarAboutToBlow(object sender, CarEventArgs e) { Console.WriteLine ("{0} сообщает: {1}", sender, e.msg); }

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

public static void CarIsAlmostDoomed(object sender, CarEventArgs e) {
 // Просто для гарантии здесь перед вызовом предлагается
 // проверка среды выполнения.
 if (sender is Car) {
  Car с = (Car)sender;
  c.CrankTunes(false);
 }
 Console.WriteLine("Важное сообщение от {0}: {1}", sender, e.msg);
}

Исходный код. Проект PrimAndProperCarEvenfs размещен в подкаталоге, соответствующем главе 8.

Оглавление книги


Генерация: 2.019. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз