Читаем Язык программирования С# 2005 и платформа .NET 2.0. полностью

 private Exploded explodedList;

 // Добавление элементов в список вызовов

 // с помощью вспомогательных методов.

 public void OnAboutToBlow(AboutToBlow clientMethod) {almostDeadList = clientMethod;}

 public void OnExploded(Exploded clientMethod) {explodedList = clientMethod;}

 …

}

Обратите внимание на то, что в этом примере мы определяем типы делегата непосредственно в рамках типа Car. Если исследовать библиотеки базовых классов, то станет ясно, что определение делегата в рамках типа, с которым он обычно работает, является вполне типичным. В связи с этим, поскольку компилятор преобразует делегат в полное определение класса, мы здесь фактически создаем вложенные классы.

Далее обратите внимание на то, что здесь объявлены члены-переменные (по одному для каждого типа делегата) и вспомогательные функции (OnAboutToBlow() и OnExploded()), которые позволят клиенту добавлять методы в списки вызовов делегатов. В принципе эти методы подобны методам Advise() и Unadvise(), которые были нами созданы в примере с EventInterfасе. Но в данном случае входящим параметром оказывается размещаемый клиентом объект делегата, а не класс, реализующий конкретный интерфейс.

Здесь мы должны обновить метод Accelerate(), чтобы вызывались делегаты, а не просматривались объекты ArrayList приемников клиента (как это было в примере с EventInterfасе). Подходящая модификация может выглядеть так.

public void Accelerate(int delta) {

 // Если машина 'сломалась', генерируется событие Exploded.

 if (carIsDead) {

  if (explodedList != null) explodedList("Извините, машина сломалась…");

 } elsе {

  currSpeed += delta;

  // Вот-вот сломается?

  if (10 == maxSpeed – currSpeed && almostDeadList != null) {

   almostDeadList("Осторожно! Могу сломаться!");

  }

  // Пока все OK!

  if (currSpeed ›= maxSpeed) carIsDead = true;

  else Console.WriteLine("CurrSpeed = {0}", currSpeed);

 }

}

Обратите внимание на то, что перед вызовом методов, связанных с членами-переменными almostDeadList и explodedList, их значения проверяются на допустимость. Причина в том, что размещение соответствующих объектов с помощью вызова вспомогательных методов OnAboutToBlow() и OnExploded() будет задачей вызывающей стороны. Если вызывающая сторона не вызовет эти методы, а мы попытаемся получить список вызовов делегата, то будет сгенерировано исключение NullReferenseException и в среде выполнения возникнут проблемы (что, конечно же, нежелательно).

Теперь, когда инфраструктура делегата имеет нужный нам вид, рассмотрим модификацию класса Program.

class Program {

 static void Main(string[] args) {

  Console.WriteLine("***** Делегаты и контроль событий *****");

  // Обычное создание класса Car.

  Car cl = new Car("SlugBug", 100, 10);

  // Регистрация обработчиков событий для типа Car.

  cl.OnAboutToBlow(new Car.AboutToBlow(CarAboutToBlow));

  cl.OnExploded(new Car.Exploded(CarExploded));

  // Ускоряемся (при этом генерируются события) .

  Console.WriteLine("\n***** Ускорение *****");

  for(int i = 0; i ‹ 6; i++) cl.Accelerate(20);

  Console.ReadLine();

 }

 // Car будет вызывать эти методы.

 public static void CarAboutToBlow(string msg) {Console.WriteLine(msg);}

 public static void CarExploded(string msg) {Console.WriteLine(msg);}

}

Перейти на страницу:

Похожие книги

97 этюдов для архитекторов программных систем
97 этюдов для архитекторов программных систем

Успешная карьера архитектора программного обеспечения требует хорошего владения как технической, так и деловой сторонами вопросов, связанных с проектированием архитектуры. В этой необычной книге ведущие архитекторы ПО со всего света обсуждают важные принципы разработки, выходящие далеко за пределы чисто технических вопросов.?Архитектор ПО выполняет роль посредника между командой разработчиков и бизнес-руководством компании, поэтому чтобы добиться успеха в этой профессии, необходимо не только овладеть различными технологиями, но и обеспечить работу над проектом в соответствии с бизнес-целями. В книге более 50 архитекторов рассказывают о том, что считают самым важным в своей работе, дают советы, как организовать общение с другими участниками проекта, как снизить сложность архитектуры, как оказывать поддержку разработчикам. Они щедро делятся множеством полезных идей и приемов, которые вынесли из своего многолетнего опыта. Авторы надеются, что книга станет источником вдохновения и руководством к действию для многих профессиональных программистов.

Билл де Ора , Майкл Хайгард , Нил Форд

Программирование, программы, базы данных / Базы данных / Программирование / Книги по IT