A while ago Charlie Calvert did a great job explaining delegates here. Readers were asking for more samples that would demonstrate the benefits of delegates. After a lot of hard thinking (somehow it's hard to find an easy sample!) I've come up with a simple sample which will hopefully demonstrate just that. Sorry if you don't like it.
Suppose you are designing some classes that have a DisplayHelp() method:
public void DisplayHelp() { Console.WriteLine("tf get itemspec"); Console.WriteLine(" "); Console.WriteLine(" Retrieves a read-only copy of a file "); Console.WriteLine(" from Team Foundation Server to the local workspace "); Console.WriteLine(" and creates folders on disk to contain it."); }
See how Console.WriteLine is repeated every time? What if you have to output help to a file stream instead? You'll have to change all the lines of code.
Solution: you could abstract away the logic of outputting from the actual help contents and pass this logic as a parameter:
public void DisplayHelp(Action<string> print) { print("tf get itemspec"); print(" "); print(" Retrieves a read-only copy of a file "); print(" from Team Foundation Server to the local workspace "); print(" and creates folders on disk to contain it."); }
Now you can pass the output algorithm as an argument to the DisplayHelp method:
command.DisplayHelp(Console.WriteLine);
or, for printing to a file:
using (var writer = new StreamWriter(@"c:\help.txt")) { command.DisplayHelp(writer.WriteLine); }
From my experience, if you have a complex hierarchy with many classes, and each of them has an output method similar to DisplayHelp, this approach actually turns out quite useful. The more I learn about programming, the more I use delegates in more and more contexts.
Note: An equally flexible approach would be using yield return to return the strings, but the yield return approach doesn't compose very well.
Another note: we could actually redirect the standard output using the Console.SetOut() method, but that would defeat the whole purpose of demonstrating delegates :)
So how do we know where to use delegates? Potentially you can use delegates wherever you use an interface with a single method (such as e.g. IDisposable). Whether you actually want to do so, remains a matter of personal preference.
PingBack from http://blog.cwa.me.uk/2008/02/11/the-morning-brew-29/