Язык программирования C#9 и платформа .NET5
Часть 239 из 642 Информация о книге
{_listOfHandlers += methodToCall;}...}Когда операция
используется с объектом делегата, компилятор преобразует ее в вызов статического метода+=. На самом деле можно было бы вызыватьDelegate.Combine()напрямую, однако операцияDelegate.Combine()предлагает более простую альтернативу. Хотя нет никакой необходимости в модификации текущего метода+=, ниже представлен пример примененияRegisterWithCarEngine()вместо операцииDelegate.Combine():+=public void RegisterWithCarEngine( CarEngineHandler methodToCall ){if (_listOfHandlers == null){_listOfHandlers = methodToCall;}else{_listOfHandlers =Delegate.Combine(_listOfHandlers, methodToCall)as CarEngineHandler;}}В любом случае вызывающий код теперь может регистрировать множественные цели для одного и того же обратного вызова. Второй обработчик выводит входное сообщение в верхнем регистре просто ради отображения:
Console.WriteLine("***** Delegates as event enablers *****\n");// Создать объект Car.Car c1 = new Car("SlugBug", 100, 10);<b>// Зарегистрировать несколько обработчиков событий.</b>c1.RegisterWithCarEngine(new Car.CarEngineHandler(OnCarEngineEvent));c1.RegisterWithCarEngine(new Car.CarEngineHandler(OnCarEngineEvent2));<b>// Увеличить скорость (это инициирует события).</b>Console.WriteLine("***** Speeding up *****");for (int i = 0; i < 6; i++){c1.Accelerate(20);}Console.ReadLine();<b>// Теперь есть ДВА метода, которые будут</b><b>// вызываться Car при отправке уведомлений.</b>static void OnCarEngineEvent(string msg){Console.WriteLine("\n*** Message From Car Object ***");Console.WriteLine("=> {0}", msg);Console.WriteLine("*********************************\n");}static void OnCarEngineEvent2(string msg){Console.WriteLine("=> {0}", msg.ToUpper());}Удаление целей из списка вызовов делегата
В классе
также определен статический методDelegate, который позволяет вызывающему коду динамически удалять отдельные методы из списка вызовов объекта делегата. В итоге у вызывающего кода появляется возможность легко "отменять подписку" на заданное уведомление во время выполнения. Хотя методRemove()допускается вызывать в коде напрямую, разработчики C# могут использовать в качестве удобного сокращения операциюDelegate.Remove(). Давайте добавим в класс-=новый метод, который позволяет вызывающему коду исключать метод из списка вызовов:Carpublic class Car{...public void UnRegisterWithCarEngine(CarEngineHandler methodToCall){_listOfHandlers -= methodToCall;}}При таком обновлении класса
прекратить получение уведомлений от второго обработчика можно за счет изменения вызывающего кода следующим образом:CarConsole.WriteLine("***** Delegates as event enablers *****\n");// Создать объект Car.Car c1 = new Car("SlugBug", 100, 10);c1.RegisterWithCarEngine(new Car.CarEngineHandler(OnCarEngineEvent));<b>// На этот раз сохранить объект делегата, чтобы позже</b><b>// можно было отменить регистрацию.</b>Car.CarEngineHandler handler2 =new Car.CarEngineHandler(OnCarEngineEvent2);c1.RegisterWithCarEngine(handler2);// Увеличить скорость (это инициирует события).Console.WriteLine("***** Speeding up *****");for (int i = 0; i < 6; i++){c1.Accelerate(20);}<b>// Отменить регистрацию второго обработчика.</b>