An event is really just an “add” operation and a “remove” operation. You can’t get the value, you can’t set the value, you can’t call it – you can just subscribe a handler for the event (add) or unsubscribe one (remove). This is fine – it’s encapsulation, plain and simple. It’s up to the publisher to implement add/remove appropriately, but unless the publisher chooses to make the details available, subscribers can’t modify or access the implementation-specific parts.
Field-like events in C# (where you don’t specify the add/remove bits) hide this – they create a variable of a delegate type and an event. The event’s add/remove implementations just use the variable to keep track of the subscribers.
Inside the class you refer to the variable (so you can get the currently subscribed delegates, execute them etc) and outside the class you refer to the event itself (so only have add/remove abilities).
The alternative to field-like events is where you explicitly implement the add/remove yourself, e.g.
private EventHandler clickHandler; // Normal private field
public event EventHandler Click
{
add
{
Console.WriteLine("New subscriber");
clickHandler += value;
}
remove
{
Console.WriteLine("Lost a subscriber");
clickHandler -= value;
}
}
See my article on events for more information.
Of course the event publisher can also make more information available – you could write a property like ClickHandlers to return the current multi-cast delegate, or HasClickHandlersto return whether there are any or not. That’s not part of the core event model though.