An event is a notification that something has occurred (such as a mouse click) or, in some cases, is about to occur (such as a price change).
Classes can define events and their instances (objects) may raise these events. For instance, a Button may contain a Click event that gets raised when a user has clicked it.
Event handlers are then methods that get called when their corresponding event is raised. A form may contain a Clicked event handler for every Button it contains, for instance.
EventArgsT: The type that derives from EventArgs and contains the event parameters.
- EventName : The name of the event.
- HandlerName : The name of the event handler.
- SenderObject : The object that’s invoking the event.
- EventArguments : An instance of the EventArgsT type that contains the event parameters.|
When raising an event:
- Always check if the delegate is
null. A null delegate means the event has no subscribers. Raising an event with no subscribers will result in a
- Copy the delegate (e.g.
EventName) to a local variable (e.g.
eventName) before checking for null / raising the event. This avoids race conditions in multi-threaded environments:
if (Changed != null) // Changed has 1 subscriber at this point // In another thread, that one subscriber decided to unsubscribe Changed(this, args); // `Changed` is now null, `NullReferenceException` is thrown.
// Cache the "Changed" event as a local. If it is not null, then use // the LOCAL variable (handler) to raise the event, NOT the event itself. var handler = Changed; if(handler != null) handler(this, args);
- Use the null-conditional operator (?.) for raising the method instead of null-checking the delegate for subscribers in an
EventName?.Invoke(SenderObject, new EventArgsT());
- When using Action<> to declare delegate types, the anonymous method / event handler signature must be the same as the declared anonymous delegate type in the event declaration.