Книга: ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание

Глубинный механизм событий

Глубинный механизм событий

Событие в C# представляется двумя скрытыми общедоступными методами, один из которых имеет префикс add_, а другой – префикс remove_. За этими префиксами следует имя события. Например, событие Exploded транслируется в пару CIL-методов с именами add_Exploded() и remove_Exploded(). Кроме приведения к методам add_XXX() и remove_XXX(), определение события на уровне CIL связывает данное событие с соответствующим делегатом.

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

.method public hidebysig specialname instance void add_AboutToBlow(class CarEvents.Car/CarEventHandler 'value') cil managed synchronized {
 .maxstack 8
 ldarg.0
 ldarg.0
 ldfld class CarEvents.Car/CarEventHandler CarEvents.Car::AboutToBlow
 ldarg.1
 call class [mscorlib]System.Delegate [mscorlib] System.Delegate::Combine(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)
 castclass CarEvents.Car/CarEventHandler
 stfld class CarEvents.Car/CarEventHandler
 CarEvents.Car::AboutToBlow
 ret
}

В соответствии с ожиданиями, метод remove_AboutToBlow() неявно (опосредованно) вызывает Delegate.Remove() и приблизительно соответствует определенному выше вспомогательному методу RemoveAboutToBlow().

.method public hidebysig specialname instance void remove_AboutToBlow(class CarEvents.Car/CarEventHandler 'value') cil managed synchronized {
 .maxstack 8
 ldarg.0
 ldarg.0
 ldfld class CarEvents.Car/CarEventHandler CarEvents.Car::AboutToBlow
 ldarg.1
 call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)
 castclass CarEvents.Car/CarEventHandler
 stfld class CarEvents.Car/CarEventHandler CarEvents.Car::AboutToBlow
 ret
}

Наконец, программный код CIL, представляющий само событие, использует директивы .addon и .removeon для отображения имен в соответствующие имена вызываемых методов add_XXX() и remove_XXX().

.event CarEvents.Car/EngineHandler AboutToBlow {
 .addon void CarEvents.Car::add_AboutToBlow(class CarEvents.Car/CarEngineHandler)
 .removeon void CarEvents.Car::remove_AboutToBlow(class CarEvents.Car/CarEngineHandler)
}

Теперь, когда вы знаете, как строить классы, способные посылать события в C# (и знаете о том, что соответствующая событиям синтаксическая конструкция – это просто сокращение, позволяющее уменьшить объем вводимых с клавиатуры данных), мы должны выяснить, как осуществляется "прием" поступающих событий с точки зрения вызывающей стороны.

Оглавление книги


Генерация: 1.315. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз