Free mag vol1 | Page 439

CHAPTER 10  DELEGATES, EVENTS, AND LAMBDA EXPRESSIONS Understanding C# Events Delegates are fairly interesting constructs in that they enable objects in memory to engage in a two-way conversation. However, working with delegates in the raw can entail the creation of some boilerplate code (defining the delegate, declaring necessary member variables, and creating custom registration and unregistration methods to preserve encapsulation, etc.). Moreover, when you use delegates in the raw as your application’s callback mechanism, if you do not define a class’s delegate member variables as private, the caller will have direct access to the delegate objects. In this case, the caller could reassign the variable to a new delegate object (effectively deleting the current list of functions to call) and, worse yet, the caller would be able to directly invoke the delegate’s invocation list. To illustrate this problem, consider the following reworking (and simplification) of the Car class from the previous CarDelegate example: public class Car { public delegate void CarEngineHandler(string msgForCaller); // Now a public member! public CarEngineHandler listOfHandlers; } // Just fire out the Exploded notification. public void Accelerate(int delta) { if (listOfHandlers != null) listOfHandlers("Sorry, this car is dead..."); } Notice that we no longer have private delegate member variables encapsulated with custom registration methods. Because these members are indeed public, the caller can directly access the listOfHandlers member variable and reassign this type to new CarEngineHandler objects and invoke the delegate whenever it so chooses: class Program { static void Main(string[] args) { Console.WriteLine("***** Agh! No Encapsulation! *****\n"); // Make a Car. Car myCar = new Car(); // We have direct access to the delegate! myCar.listOfHandlers = new Car.CarEngineHandler(CallWhenExploded); myCar.Accelerate(10); // We can now assign to a whole new object... // confusing at best. myCar.listOfHandlers = new Car.CarEngineHandler(CallHereToo); myCar.Accelerate(10); // The caller can also directly invoke the delegate! myCar.listOfHandlers.Invoke("hee, hee, hee..."); Console.ReadLine(); 378