When you have worked with the same technology day-in, day-out for almost 15 years, it’s easy to miss some of the “under-the-radar” changes that are made without any fan-fare. This, for me, is one of those in C#.
I couldn’t tell you how many times a day I write code similar to the following, which is a staple of object-oriented, event-driven programming – used to fire an event if something is listening to it:
public class MyClass
{
public event Action MyEvent;
public void OnMyEvent()
{
if (this.MyEvent != null)
{
this.MyEvent.Invoke();
}
}
}
Since I switched to Visual Studio 2015 earlier this year, it always suggests this code with the improvement: “delegate invocation can be simplified.” Up until now I’ve ignored it, because I didn’t see how this simple code could be improved – all I’m doing is invoking an event if it’s not null, it doesn’t get much simpler. Does it?
Just for kicks, I let Visual Studio modify one such block and was amazed at the result:
public class MyClass
{
public event Action MyEvent;
public void OnMyEvent()
{
this.MyEvent?.Invoke();
}
}
This code looks strange to begin with – until you make a comparison with the ?? operator. It’s simply saying “if the object on the left of the ? operator is not null, then invoke the method on the right” in the same way that ?? says “if the value on the left of the ?? operator is not null, then use it, otherwise use the value on the right.”
The same technique therefore works with any object, and any method, as illustrated below!
var c = anObject as MyClass;
// If the above conversion fails, "c" will be null, and SomeMethod() won't be invoked,
// thus preventing the dreaded "Object reference not set..." exception
c?.SomeMethod();
I’m still deciding if this is considered “good” syntax from a readability perspective, but I’ve already started using it in my day-to-day coding, and it certainly saves those keystrokes and feels natural when you’re typing it!