Вход/Регистрация
ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание
вернуться

Троелсен Эндрю

Шрифт:

public class Car {

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

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

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

 ...

}

Здесь синтаксис -= тоже выступает в качестве простого сокращения для вызова статического метода Delegate.Remove, что доказывается следующим программным кодом CIL для члена RemoveAboutToBlow типа Car.

.method public hidebysig instance void RemoveAboutToBlow(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::Remove(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)

 castclass CarDelegate.Car/AboutToBlow

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

 ret

}

Если вызывающая сторона пожелает удалить элемент из списка вызовов делегата, мы должны предоставить тот же объект делегата, который был ранее добавлен. Поэтому мы можем прекратить выдачу сообщения Exploded, обновив Main так, как показано ниже.

static void Main(string[] args) {

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

 // Сохранение объекта Car.Exploded делегата.

 Car.Exploded d = new Car.Exploded(CarExploded);

 cl.OnExploded(d);

 …

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

 cl.RemoveExploded(d);

 …

}

Вывод нашего приложения CarDelegate показан на рис. 8.5.

Рис. 8.5. Приложение CarDelegate за работой

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

Более совершенный пример делегата

Чтобы продемонстрировать более интересные варианты использования делегатов, мы добавим в класс Car пару членов-переменных логического типа. Первый из добавляемых членов предназначен для индикации того, что автомобиль необходимо помыть (isDirty), а второй будет сообщать о том, что автомобиль требует замены шин (shouldRotate). Чтобы позволить пользователю объекта взаимодействовать с этими новыми данными состояния, для Car определяются необходимые дополнительные свойства и обновляется конструктор. Вот как выглядит соответствующим образом модифицированный программный код.

// Обновленный класс Car.

public class Car {

 …

 // Не пора ли помыть? Не пора ли сменить шины?

 private bool isDirtу;

 private bool shouldRotate;

 // Дополнительные параметры для установки булевых значений.

 public Car(string name, int maxSp, int currSp, bool washCar, bool rotateTires) {

…

isDirty = washCar;

shouldRotate = rotateTires;

 }

 public bool Dirty {

get { return isDirty; }

set { isDirty = value; }

 }

 public bool Rotate {

get { return shouldRotate; }

set { shouldRotate = value; }

 }

}

Также предположим, что в тип Car вложен новый делегат CarDelegate.

// Для Car определяется еще один делегат.

public class Car {

 …

 // Может вызывать любой метод, получающий Car в виде параметра

 // и не возвращающий ничего.

 public delegate void CarDelegate(Car с);

 …

}

Здесь создается делегат с именем CarDelegate. Тип CarDelegate представляет "некоторую функцию", принимающую Car в качестве параметра и возвращающую пустое значение.

  • Читать дальше
  • 1
  • ...
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: