6

I have looking at an old piece of code and cannot somehow understand the following:

public event EventHandler NameChanged;
#endregion

#region protected void OnNameChanged(EventArgs args)
/// <summary>
/// Raises NameChanged event.
/// </summary>
/// <param name="args">Event arguments.</param>
protected void OnNameChanged(EventArgs args)
{
    EventHandler eh = this.NameChanged;
    if (eh != null)
    {
        eh(this, args);
    }
}

Why is the event raised by an invocation of the delegate? Could I not simply call the event itself (NameChanged) as usual?

EDIT: I can see this is also suggested on MSDN: https://learn.microsoft.com/en-us/dotnet/standard/events/

User039402
  • 219
  • 1
  • 4
  • It is for thread-safety: https://stackoverflow.com/questions/30759836/why-is-the-standard-c-sharp-event-invocation-pattern-thread-safe-without-a-memor/32031477#32031477 – rene Aug 20 '17 at 07:11

1 Answers1

3

Whenever you reference an event, you are in fact copying the invocation list to the local reference. By doing that, you make sure that between checking the validity of the event eh != null and invoking the event eh(this, args)eh's value wouldn't change (maybe from a different thread).

In C# 6, there is a new operator https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators

You could just do this instead:

NameChanged?.Invoke(this, args);
areller
  • 4,800
  • 9
  • 29
  • 57
  • "maybe from a different thread"? It would have to be from another thread. – Enigmativity Aug 20 '17 at 07:16
  • Well so the good, old NameChanged() should not be used anymore? – User039402 Aug 20 '17 at 07:17
  • 1
    @User039402 - It should never be used if you want to ensure thread-safety. – Enigmativity Aug 20 '17 at 07:19
  • @Enigmativity right, before null conditional operators, you had to copy the event to the local thread, explicitly check for nullity, and only then fire the event. – areller Aug 20 '17 at 07:22
  • Wow, that is completely new to me. So I could delete the whole OnNameChanged method and replace with the NameChanged?.Invoke...right? – User039402 Aug 20 '17 at 07:25
  • @User039402 If you are writing in C# 6, then yes. But still, it is important that you understand the idea behind copying the event to a local variable and null checking it. – areller Aug 20 '17 at 07:29