8

I've always invoked events as so

void onSomeEvent(string someArg) {
    var h = this.EventName;
    if (h != null) {
        h(this, new MyEventArgs(someArg));
    }
}

Today VS 2015 tells me this can be simplified:

MyEvent?.Invoke(this, new MyEventArgs(someArg));

A few questions on this latter method, which I've not seen before:

  1. Presumably the ? after the event name is a check if the handler is null?
  2. Assuming the handler is not null, .Invoke() seems straightforward enough
  3. I've used the first example for years and realize it prevents race conditions... presumably the ?.Invoke() of the second example does so as well?
jleach
  • 7,410
  • 3
  • 33
  • 60
  • Why do you think the new syntax would read it twice when it only appears once in the source? – SLaks May 06 '16 at 15:48
  • @SLaks - I don't know. Perhaps it's my lack of understanding of what actually causes the race condition, which you (and Jon) seem to be implying is caused by it being read more than once? – jleach May 06 '16 at 15:49
  • I don't know who wrote the code to recognize that particular code pattern and determine that I could use a new feature to implement it instead... one of the many reasons that VS is the most impressive IDE I've ever seen. – jleach May 06 '16 at 16:11
  • @jdl134679 Stick [ReSharper](https://www.jetbrains.com/resharper/) on top of it, it gets even better :) – James Thorpe May 06 '16 at 16:11

1 Answers1

8

Presumably the ? after the event name is a check if the handler is null?

Yes. It's the null conditional operator, introduced in C# 6. It's useful in all kinds of ways.

I've used the first example for years and realize it prevents race conditions... presumably the ?.Invoke() of the second example does so as well? (see question #1)

Yes. Basically, they're equivalent. In particular, it does not evaluate the MyEvent expression twice. It evaluates it once, and then if the result is non-null, it calls Invoke on it.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thanks Jon... can you please see my Edit and offer an insight on that just to be sure? (edit: there seems to be some implication that the race condition I've always prevented is caused by reading MyEvent twice... this was unknown to me) – jleach May 06 '16 at 15:47
  • 4
    @jdl134679: Yes, the race condition in `if (MyEvent != null) { MyEvent.Invoke(...); }` is indeed caused by reading it twice - because it can be non-null the first time, then null the second time. So you need to read it just once. You can do that storing the value in a local variable, or using the null conditional operator. – Jon Skeet May 06 '16 at 16:00
  • 1
    This is pretty slick looking: https://msdn.microsoft.com/en-us/library/dn986595.aspx (ref on the C# 6.0 null-conditional). I expect I will find a number of uses for this one. Thanks again! – jleach May 06 '16 at 16:05