Let's consider the two ways to declare events.
Either you declare an event using an explicit add
/remove
method, or you declare an event without such methods.
In other words, you declare the event like this:
public event EventHandlerType EventName
{
add
{
// some code here
}
remove
{
// some code here
}
}
or you declare it like this:
public event EventHandlerType EventName;
The thing is, in some ways they're the same thing, and in other ways, they're completely different.
From the perspective of outside code, that is ... code outside of the class publishing the event, they're the exact same thing. To subscribe to an event, you call a method. To unsubscribe, you call a different method.
The difference is that in the second example code above, those methods will be provided by the compiler for you, however, that's still how it's going to be. To subscribe to the event, you call a method.
The syntax to do so, in C#, however, is the same, you do either:
objectInstance.EventName += ...;
or:
objectInstance.EventName -= ...;
So from the "outside perspective", the two ways are no different at all.
However, inside the class, there is a difference.
If you try to access the EventName
identifier inside the class, you're actually referring to the field
that backs the property, but only if you use the syntax that doesn't explicitly declare an add
/remove
method.
A typical pattern is like this:
public event EventHandlerType EventName;
protected void OnEventName()
{
var evt = EventName;
if (evt != null)
evt(this, EventArgs.Empty);
}
In this case, when you're referring to EventName
, you're actually referring to the field that holds the delegate of type EventHandlerType
.
However, if you've explicitly declared the add
/remove
methods, referring to the EventName
identifier inside the class will be just like outside of the class, since the compiler cannot guarantee that it knows the field, or any other mechanism, in which you store the subscription.