Why use events for what I can do with Delegates?
The main purpose of events is to prevent subscribers from interfering with each other. If you do not use events, you can:
Replace other subscribers by reassigning delegate(instead of using the += operator), Clear all subscribers (by setting delegate to null), Broadcast to other subscribers by invoking the delegate.
Source: C# in a Nutshell
Imagine you have 3 subscribers who are interested in your someEvent. Let's further imagine they are interested in receiving events from the same EventTester
instance. For brevity, let's leave out the details of how the exact same instance is passed to all the clients. When I say clients, I mean any class who is a subscriber to the event.
Here is the instance:
EventTester evt = new EventTester();
They have subscribed to the event of the above instance as shown below:
Client 1
evt.someEvent += Client1Handler1;
evt.someEvent += Client1Handler2;
Client 2
evt.someEvent += Client2Handler1;
Client 3
evt.someEvent += Client3Handler1;
evt.someEvent += Client3Handler2;
Client 4:
Imagine client 4 did one of the 3 below:
// 1: See Note 1 below
evt.someEvent = null;
// 2: See Note 2 below
evt.someEvent = new someEventDelegate(MyHandler);
// 3: See Note 3 below
evt.someEvent();
//...
private void MyHandler()
{
MessageBox.Show("Client 4");
}
Note 1
Client 1, 2, and 3 will not be getting any events anymore. Why? Because Client 4 just did this evt.someEvent = null;
and in EventTester
you have this line of code:
if (someEvent != null) someEvent();
Since that condition will not pass anymore, no event will be raised. There is nothing wrong with the above line of code by the way. But there is the problem with using delegates: It can be assigned to.
Note 2
It has been completely over-written to a brand new instance. Now regardless of the client, they will all see a message box that says "Client 4".
Note 3
Ooops all of a sudden one of the clients is broadcasting the event.
Imagine for a second EventTester
was a Button
and someEvent
was Click
. Imagine you had multiple clients interested in the click event of this button. All of a sudden, one client decides no-one else should get notifications (Note 1). Or one client decides that when the button is clicked, it will be handled only 1 way (Note 2). Or it has made the decision that it will decide when a button is clicked even though the button may not have been clicked (Note 3).
If you have an event
and one of the clients tried the above, they will not be allowed and get a compile error, like this:
Sure, you can use delegates because behind the scenes an event is a construct that wraps a delegate.
But the rationale of using events instead of delegates is the the same as for using properties instead of fields - data encapsulation. It's bad practice to expose fields (whatever they are - primitive fields or delegates) directly.
By the way, you missed a public
keyword before your delegate field to make it possible in the second snippet.
Another "by the way" with the second snippet: for delegates you should use Delegate.Combine
instead of "+=".