9 Answers
9

Using a delegate allows the programmer to encapsulate a reference to a method inside a delegate object. The delegate object can then be passed to code which can call the referenced method, without having to know at compile time which method will be invoked.
In reality:

Delegate object is an envelope.
In the envelope (delegate object) there is a phone number (referenced method) to an unknown person (method), the receiver of envelope (delegate object) can call that number (referenced method), now here you can tell (delegate parameter) that person to do something interesting.

Imagine I am your boss (a fearsome prospect, I know). One day, I show up with a colleague and say to you:

"I delegate responsibility for doing
something to this person. They are my
delegate, and you should ask them if
you need anything done. They may ask
me to do it, or they may do it
themselves. Either way, it gets done
and you don't need to know who did
it."

That's it.

All your programmers have to do now is understand that there is a hidden reference to an object behind the presented delegate.

A delegate is like a blank cheque. You can write a cheque for bank accounts you have access to. You can give that cheque to someone else, who perhaps does not have access to that bank account. The cheque can pass hands until someone writes in an amount and cashes it in, which instructs the bank to withdraw money from that account and give it to that person. The person caching in the cheque might not even know the person who wrote the cheque or the owner of the bank account.

The best example I ever heard is a parent-teenager relationship. A teenager's friend asks her to hang out on a Friday night, but the teenager has to ask her parents (her delegate) for permission first.

If they have a background (C/C++) for it then explaining that it's a strongly typed function pointer may be sufficient albeit not 100% accurate. I honestly felt that I really grokked them once I started working with LINQ to objects.