Free mag vol1 | Page 436

CHAPTER 10  DELEGATES, EVENTS, AND LAMBDA EXPRESSIONS } static void StringTarget(string arg) { Console.WriteLine("arg in uppercase is: {0}", arg.ToUpper()); } static void IntTarget(int arg) { Console.WriteLine("++arg is: {0}", ++arg); } } } Notice that MyGenericDelegate defines a single type parameter that represents the argument to pass to the delegate target. When creating an instance of this type, you are required to specify the value of the type parameter, as well as the name of the method the delegate will invoke. Thus, if you specified a string type, you send a string value to the target method: // Create an instance of MyGenericDelegate // with string as the type parameter. MyGenericDelegate strTarget = new MyGenericDelegate(StringTarget); strTarget("Some string data"); Given the format of the strTarget object, the StringTarget() method must now take a single string as a parameter: static void StringTarget(string arg) { Console.WriteLine("arg in uppercase is: {0}", arg.ToUpper()); }  Source Code The GenericDelegate project is located under the Chapter 10 subdirectory. The Generic Action<> and Func<> Delegates Over the course of this chapter, you have seen that when you want to use delegates to enable callbacks in your applications, you typically follow the steps shown here: • Define a custom delegate that matches the format of the method being pointed to. • Create an instance of your custom delegate, passing in a method name as a constructor argument. • Invoke the method indirectly, via a call to Invoke() on the delegate object. When you take this approach, you typically end up with a number of custom delegates that might never be used beyond the current task at hand (e.g., MyGenericDelegate, CarEngineHandler, and so forth). While it may certainly be the case that you do indeed need to have a custom, uniquely named 375