Events are an implementation of the observer pattern.
An event is implemented as a list of methods to be called when the vent is raised.
Delegates are method references: in contrast to Java, C# offers a way to refer to a method.
It's not a priori better to use events than implement the observer pattern oneself. But events offer a quite generic way to do it, and are in many cases highly optimized for the task, thus give a more efficient and convenient way organize this.
A delegate is defined by the signature of the expected method. For instance with:
public delegate void FooMethod (Bar x, Baz y);
You define a delegate for void methods given a Bar and a Baz. So if you have an instance of the following class:
public class Qux { public void Method (Bar x, Baz y) { //do something return null; } }
Then you can refer to the method:
Qux q = new Qux(); FooMethod fm = q.Method;
An event is thus a list of delegates with the same signature:
You define an event as:
private event FooMethod SomeEvent;
You can add delegates (listeners) by using the += operator:
SomeEvent += q.Method;
remove the delegate by the -= operator and call the event with:
SomeEvent(new Bar(), new Baz());
As if you call a single method that does the dispatching.
By calling the event, all the registered delegates will be called, in the order of registration.
Note: By calling SomeEvent(new Bar(), new Baz()); this does not mean every delegate receives new instances: the instances are constructed first and shared over all delegate calls.
Conclusion: I think the C# designers did a good job introducing observer patterns since the programmer is no longer responsible to program it correctly his/herself. Furthermore the events are easy to understand and use convenient syntax. In special situations however programmers can be required to implement an observer him/herself. But these are very rare occasions.