If the event is marked with the C# event keyword then there's no way from outside the object to see the subscribers - the requisite information is just not visible.
From inside, it can be done, though it is complex and relies on details of implementation that might change (though, they haven't yet).
A workaround that might be useful for you though, is that it's valid to remove a handler that's not there - no exception is thrown.
So this code is valid:
myConnection.Closing -= ConnectionClosingHandler;
myConnection.Closing += ConnectionClosingHandler;
If you're already subscribed to the event, the first line removes the subscription.
If you're not already subscribed to the event, the first line does nothing.
The second line then hooks up a new subscription, and you're guaranteed not to be notified multiple times.
To answer your last bullet point, when you declare a normal event:
public event PropertyChangedEventHandler Changed;
The compiler creates a member variable of type PropertyChangedEventHandler
which stores all the subscribers. You can take over storage if you want:
public event PropertyChangedEventHandler Changed
{
add { ... }
remove { ... }
}
The use of -=
and +=
to modify the subscription isn't syntactic sugar - the delegates are immutable, and a new instance is returned when you add or remove a handler. Have a look at Delegate
and MulticastDelegate
(both MSDN links) for more information on how this works.