Interfaces Vs. Delegates (or Events)
Obviously, I'm not the first to write on this topic:
The Delegates Tutorial on MSDN has some guidelines (scroll near the end, "Delegates vs. Interfaces").
Anders Hejlsberg talks about design and performance issues in Delegates, Components, and Simplexity
Jon Shemitz talks about performance too in Delegates vs. Interfaces (this article has been web-published almost everywhere).
Don Box has some thoughts about design issues in Are delegates the moniker of .NET? (never mind the weird title :-). GotDotNet seems to have major problems :-), so here comes the Google Cache to the rescue (scroll down and you'll find it).
Overall, those articles draw a pretty confused picture :-))) so I'll throw in some colors myself :-). More seriously, sooner or later I'll publish something more comprehensive (and definitive :-) on the subject, but right now, I just want to add a few thoughts about design with interfaces Vs. delegates.
Interfaces and Delegates are both contracts. The implementer has to respect the syntactic contract (typing, and names when you use interfaces). The caller has a role in the contract too - I'll be back to this in a short while, as it makes a difference. Delegates are a "weaker" form of contract (Hejlsberg and Box both seem to agree on this point, although they use different words/metaphors). It is weaker because:
1) it does not group together a set of functions
2) it does not force the name of the method
3) it does not force the method to be a member
4) it does not give identity to the callee
I'll give attention only to (4) right now, because it has been somewhat ignored by other authors. When you implement an interface, and you pass a reference to that interface to someone, you're engaging in a contract which says: whenever you call one of those functions, the same object will handle the call [in different methods]. When you expose a set of delegates, you don't have that guarantee. Calls could be redirected to different objects. This breaks the idea of an interface as a whole contract, switching to a model of methods [delegates, actually] as individual contracts. For most people, that means additional freedom and is therefore welcome. However, the lack of an overall contract is not necessarily a good thing. An interface, in UML 2 speaking, may have an associated Protocol State Machine. A PSM is a behavioral contract, opposed to the syntactic contract most people think about. A behavioral contract is a constraint on both sides: the caller must call functions in a specified order, when the callee is in specified (although abstract) states. However, the contract makes sense because there is one, well determined receiver. You can't enforce a contract among a scattered group of delegates.
Bottom line: read the stuff linked above, but add this: if the concept you have in mind is a single contract, encompassing multiple functions, possibly with an associated PSM, use an interface. If you only have individual contracts in your mind, you can use delegates.
For more on PSM, my italian readers may want to read my UML 2 Manuale di Stile.