Free mag vol1 | Page 446

CHAPTER 10  DELEGATES, EVENTS, AND LAMBDA EXPRESSIONS For simple events, you can pass an instance of EventArgs directly. However, when you want to pass along custom data, you should build a suitable class deriving from EventArgs. For our example, assume you have a class named CarEventArgs, which maintains a string representing the message sent to the receiver: public class CarEventArgs : EventArgs { public readonly string msg; public CarEventArgs(string message) { msg = message; } } With this, you would now update the CarEngineHandler delegate type definition as follows (the events would be unchanged): public class Car { public delegate void CarEngineHandler(object sender, CarEventArgs e); ... } Here, when firing the events from within the Accelerate() method, you would now need to supply a reference to the current Car (via the this keyword) and an instance of the CarEventArgs type. For example, consider the following partial update: public void Accelerate(int delta) { // If the car is dead, fire Exploded event. if (carIsDead) { if (Exploded != null) Exploded(this, new CarEventArgs("Sorry, this car is dead...")); } ... } On the caller’s side, all you would need to do is update your event handlers to receive the incoming parameters and obtain the message via the read-only field. For example: public static void CarAboutToBlow(object sender, CarEventArgs e) { Console.WriteLine("{0} says: {1}", sender, e.msg); } If the receiver wants to interact with the object that sent the event, you can explicitly cast the System.Object. From this reference, you can make use of any public member of the object that sent the event notification: public static void CarAboutToBlow(object sender, CarEventArgs e) { // Just to be safe, perform a // runtime check before casting. if (sender is Car) 385