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