You can declare an event on any class
or struct
using the following syntax:
public class MyClass
{
// Declares the event for MyClass
public event EventHandler MyEvent;
// Raises the MyEvent event
public void RaiseEvent()
{
OnMyEvent();
}
}
There is an expanded syntax for declaring events, where you hold a private instance of
the event, and define a public instance using add
and set
accessors. The syntax is very similar to C# properties. In all cases, the syntax demonstrated above should be preferred, because the compiler emits code to help ensure that multiple threads can safely add and remove event handlers to the event on your class.
private void OnMyEvent()
{
EventName?.Invoke(this, EventArgs.Empty);
}
private void OnMyEvent()
{
// Use a local for EventName, because another thread can modify the
// public EventName between when we check it for null, and when we
// raise the event.
var eventName = EventName;
// If eventName == null, then it means there are no event-subscribers,
// and therefore, we cannot raise the event.
if(eventName != null)
eventName(this, EventArgs.Empty);
}
Note that events can only be raised by the declaring type. Clients can only subscribe/unsubscribe.
For C# versions before 6.0, where EventName?.Invoke
is not supported, it is a good practice to assign the event to a temporary variable before invocation, as shown in the example, which ensures thread-safety in cases where multiple threads execute the same code. Failing to do so may cause a NullReferenceException
to be thrown in certain cases where multiple threads are using the same object instance. In C# 6.0, the compiler emits code similar to that shown in the code example for C# 6.