CHAPTER 10 DELEGATES, EVENTS, AND LAMBDA EXPRESSIONS
.method public hidebysig specialname instance void
add_AboutToBlow(class CarEvents.Car/CarEngineHandler 'value') cil managed
{
...
call class [mscorlib]System.Delegate
[mscorlib]System.Delegate::Combine(
class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)
...
}
As you would expect, remove_AboutToBlow() will call Delegate.Remove() on your behalf:
.method public hidebysig specialname instance void
remove_AboutToBlow(class CarEvents.Car/CarEngineHandler 'value')
cil managed
{
...
call class [mscorlib]System.Delegate
[mscorlib]System.Delegate::Remove(
class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)
...
}
Finally, the CIL code representing the event itself makes use of the .addon and .removeon directives
to map the names of the correct add_XXX() and remove_XXX() methods to invoke:
.event CarEvents.Car/EngineHandler AboutToBlow
{
.addon instance void CarEvents.Car::add_AboutToBlow
(class CarEvents.Car/CarEngineHandler)
.removeon instance void CarEvents.Car::remove_AboutToBlow
(class CarEvents.Car/CarEngineHandler)
}
Now that you understand how to build a class that can send C# events (and are aware that events
are little more than a typing time saver), the next big question is how to listen to the incoming events on
the caller’s side.
Listening to Incoming Events
C# events also simplify the act of registering the caller-side event handlers. Rather than having to specify
custom helper methods, the caller simply makes use of the += and -= operators directly (which triggers
the correct add_XXX() or remove_XXX() method in the background). When you want to register with an
event, follow the pattern shown here:
// NameOfObject.NameOfEvent += new RelatedDelegate(functionToCall);
//
Car.CarEngineHandler d = new Car.CarEngineHandler(CarExplodedEventHandler);
myCar.Exploded += d;
When you want to detach from a source of events, use the -= operator, using the following pattern:
381