
Based on this article by Chris Sells:
http://www.sellsbrothers.com/writing/default.aspx?content=delegates.htm
Part 1: Peter and his Boss
Once upon a time, in a strange land south of here, there was a worker named Peter. He was a diligent worker who would readily accept requests from his boss. However, his boss was a mean, untrusting man who insisted on steady progress reports. Since Peter did not want his boss standing in his office looking over his shoulder, Peter promised to notify his boss whenever his work progressed. Peter implemented this promise by periodically calling his boss back via a typed reference.
/*
* In Part 1 of our story, Peter has an Advise method that accepts
* a Boss instance, which has a WorkCompleted method Peter can call.
*/
Part 2: Peter and the Universe
Now Peter was a special person. Not only was he able to put up with his mean-spirited boss, but he also had a deep connection with the universe around him. So much so that he felt that the universe was interested in his progress. Unfortunately, there was no way for Peter to advise the Universe of his progress unless he added a special Advise method and special callbacks just for the Universe, in addition to keeping his boss informed. What Peter really wanted to do was to separate the list of potential notifications from the implementation of those notification methods. And so he decided to split the methods into an interface.
/*
* In Part 2 of our story, Peter refactors his notice into
* a callback interface, so anyone who implements the interface
* can register with Peter to receive notifications about his work.
*
* Peter's boss, however, must implement the WorkStarted method,
* which he doesn't care about and is, in fact, annoyed by.
*
* Sadly, the Universe is a static class, and so
* must remain oblivious to Peter and his work.
*/
Part 3: Delegates to the Rescue!
Unfortunately, Peter was so busy talking his boss into implementing this interface that he didn't get around to notifying the Universe, but he knew he would soon. At least he'd abstracted the reference of his boss far away from him so that others who implemented the IWorkerEvents interface could be notified of his work progress.
Still, his boss complained bitterly. "Peter!" his boss fumed. "Why are you bothering to notify me when you start your work or when your work is progressing?!? I don't care about those events. Not only do you force me to implement those methods, but you're wasting valuable work time waiting for me to return from the event, which is further expanded when I am far away! Can't you figure out a way to stop bothering me?"
And so, Peter decided that while interfaces were useful for many things, when it came to events, their granularity was not fine enough. He wished to be able to notify interested parties only of the events that matched their hearts' desires. So, he decided to break the methods out of the interface into separate delegate functions, each of which acted like a little tiny interface of one method each.
/*
* In Part 3 of our story, Peter reaches enlightenment and decides
* to replace his interface with delegates. That way, his Boss
* can only register for events he's interested in. The Universe
* can now finally show an interest in Peter.
*
* The problem here is that Peter breaks encapsulation, so that
* the Universe can overwrite his boss's registration. To add
* insult to injury, his boss can fire Peter's events!
*/
Part 4: Peter Encapsulates
Unfortunately, the Universe being very busy and unaccustomed to paying attention to individuals, has managed to replace Peter's boss's delegate with its own. This is an unintended side effect of making the delegate fields public in Peter's Worker class. Likewise, if Peter's boss gets impatient, he can decide to fire Peter's delegates himself (which is just the kind of rude thing that Peter's boss was apt to do).
Peter wants to make sure that neither of these can happens. He realizes he needs to add registration and unregistration functions for each delegate so that listeners can add or remove themselves, but can't clear the entire list or fire Peter's events. Instead of implementing these functions himself, Peter uses the event keyword to make the C# compiler build these methods for him.
Peter knows that the event keyword erects a property around a delegate, only allowing clients to add or remove themselves (using the += and -= operators in C#), forcing his boss and the universe to play nicely.
/*
* In Part 4 of our story, Peter decided enough is enough and
* decides to encapsulate his delegates with the C# 'event'
* keyword, which wraps his delegates in accessors so that
* others can only add and remove target methods.
*
* Best of all, this prevents Peter's boss from going overboard
* and firing his delegates willy nilly.
*
* The Universe, Peter and his Boss all live happily ever after.
*/