Free mag vol1 | Page 438

CHAPTER 10  DELEGATES, EVENTS, AND LAMBDA EXPRESSIONS } return x + y; Earlier in the chapter, I had you build a custom BinaryOp delegate to “point to” addition and subtraction methods. However, we can simplify our efforts using a version of Func<> that takes a total of three type parameters. Be aware that the final type parameter of Func<> is always the return value of the method. Just to solidify that point, assume the Program class also defines the following method: static string SumToString(int x, int y) { return (x + y).ToString(); } Now, our Main() method can call each of these methods, as so: Func funcTarget = new Func(Add); int result = funcTarget.Invoke(40, 40); Console.WriteLine("40 + 40 = {0}", result); Func funcTarget2 = new Func(SumToString); string sum = funcTarget2(90, 300); Console.WriteLine(sum); So, given that Action<> and Func<> can save you the step of manually defining a custom delegate, you might be wondering if you should use them all the time. The answer, like so many aspects of programming is “it depends.” In many cases, Action<> and Func<> will be the preferred course of action (no pun intended). However, if you need a delegate that has a custom name that you feel helps better capture your problem domain, building a custom delegate is as simple as a single code statement. You’ll see both approaches as you work over the remainder of this text.  Note Many important .NET APIs make considerable use of Action<> and Func<> delegates, including the parallel programming framework and LINQ (among others). That wraps up our initial look at the .NET delegate type. We will look at some additional details of working with delegates at the conclusion of this chapter and again in Chapter 19 during our examination of multithreading and asynchronous calls. Next, let’s move on to the related topic of the C# event keyword.  Source Code The ActionAndFuncDelegates project is located under the Chapter 10 subdirectory. 377