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

Здесь следует отметить только то, вызывающая сторона задает значения членам-переменным делегата с помощью вспомогательных методов регистрации. Кроме того, поскольку делегаты AboutToBlow и Exploded вложены в класс Car, при их размещении следует использовать полные имена (например, Car.AboutToBlow). Как любому конструктору, мы передаем конструктору делегата имя метода, который нужно добавить в список вызовов. В данном случае это два статических члена класса Program (если вложить указанные методы в новый класс, это будет очень похоже на тип CarEventSink из примера Event Interface).

Реализация групповых вызовов

Напомним, что делегаты .NET наделены возможностью группового вызова. Другими словами, объект делегата может поддерживать не один метод, а целый список доступных для вызова методов. Когда требуется добавить в объект делегата несколько методов, используется перегруженная операция +=, а не прямое присваивание. Чтобы разрешить групповой вызов для типа Car, можно обновить методы OnAboutToBlow() и OnExploded() так, как показано ниже.

public class Car {

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

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

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

 …

}

Теперь вызывающая сторона может зарегистрировать несколько целевых объектов.

class Program {

 static void Main(string[] args) {

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

  // Регистрация множества обработчиков событий.

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

  c1.OnAboutToBlow(new Car.AboutToBlow(CarlsAlmostDoomed));

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

  …

 }

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

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

 public static void CarIsAlmostDoomed(string msg) {Console.WriteLine("Важное сообщение от Car: {0}", msg);}

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

}

В программном воде CIL операция += преобразуется в вызов статического метода Delegate.Combine() (можно было бы вызвать Delegate.Combine() непосредственно, но операция += предлагает более простую альтернативу). Взгляните, например, на CIL-представление метода OnAboutToBlow().

.method public hidebysig instance void OnAboutToBlow (class CarDelegate.Car/AboutToBlow clientMethod) cil managed {

 .maxstack 8

 ldarg.0

 dup

 ldfld class CarDelegate.Car/AboutToBlow CarDelegate.Car::almostDeadList

 ldarg.1

 call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)

 castclass CarDelegate.Car/AboutToBlow

 stfld class СarDelegate.Car/AboutToBlow CarDelegate.Car::almostDeadList

 ret

}

Класс Delegate определяет также статический метод Remove(), который позволит вызывающей стороне динамически удалять элементы из списка вызовов. Легко догадаться, что в C# разработчики могут для этого использовать перегруженную операцию -=. Чтобы предоставить вызывающей стороне возможность не привязываться к обозначениям AboutToBlow и Exploded, можно добавить в тип Car следующие вспомогательные методы (обратите внимание на операцию -=).

public class Car {

 // Удаление элемента из списка вызовов.

 public void RemoveAboutToBlow(AboutToBlow clientMethod) {almostDeadList -= clientMethod;}

 public void RemoveExploded(Exploded clientMethod) {explodedList -= clientMethod;}

 ...

}

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

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

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

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

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

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