Free mag vol1 | Page 442

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