Язык программирования C#9 и платформа .NET5. Страница 243
hee, hee, hee...Очевидно, что вы не захотите предоставлять другим приложениям возможность изменять то, на что указывает делегат, или вызывать его члены без вашего разрешения. С учетом сказанного общепринятая практика предусматривает объявление переменных-членов, имеющих типы делегатов, как закрытых.
Ключевое слово event
В качестве сокращения, избавляющего от необходимости создавать специальные методы для добавления и удаления методов из списка вызовов делегата, в языке C# предлагается ключевое слово
eventeventОпределение события представляет собой двухэтапный процесс. Во-первых, понадобится определить тип делегата (или задействовать существующий тип), который будет хранить список методов, подлежащих вызову при возникновении события. Во-вторых, необходимо объявить событие (с применением ключевого слова
eventЧтобы продемонстрировать использование ключевого слова event, создайте новый проект консольного приложения по имени
CarEventsCarAboutToBlowExplodedCarEngineHandlerCarusing System;namespace CarEvents{ public class Car { ... // Этот делегат работает в сочетании с событиями Car. public delegate void CarEngineHandler(string msgForCaller);<b> // Этот объект Car может отправлять следующие события:</b> public event CarEngineHandler Exploded; public event CarEngineHandler AboutToBlow; ... }}Отправка события вызывающему коду сводится просто к указанию события по имени наряду со всеми обязательными параметрами, как определено ассоциированным делегатом. Чтобы удостовериться в том, что вызывающий код действительно зарегистрировал событие, перед вызовом набора методов делегата событие следует проверить на равенство
nullAccelerate()Carpublic void Accelerate(int delta){ // Если автомобиль сломан, то инициировать событие Exploded. if (_carIsDead) { Exploded?.Invoke("Sorry, this car is dead..."); } else { CurrentSpeed += delta;<b> // Почти сломан?</b> if (10 == MaxSpeed - CurrentSpeed) { AboutToBlow?.Invoke("Careful buddy! Gonna blow!"); }<b> // Все еще в порядке!</b> if (CurrentSpeed >= MaxSpeed) { _carIsDead = true; } else { Console.WriteLine("CurrentSpeed = {0}", CurrentSpeed); } }}Итак, класс
Car"За кулисами" событий
Когда компилятор C# обрабатывает ключевое слово event, он генерирует два скрытых метода, один с префиксом
add_remove_Explodedadd_Exploded()remove_Exploded()add_AboutToBlow()Delegate.Combine().method public hidebysig specialname instance void add_AboutToBlow( class [System.Runtime]System.EventHandler`1<class CarEvents. CarEventArgs> 'value') cil managed { ... IL_000b: call class [System.Runtime]System.Delegate [System.Runtime]System. Delegate::Combine(class [System.Runtime]System.Delegate, class [System.Runtime]System.Delegate) ...