Introduction
C# 6.0 has introduced a operator which can make coding a bit simpler and with less code. This operator is called as Elvis Operator (not officially declared) but due to its looks. => ?. two eyes and elvis hairstyle
The Elvis Operator can be used to remediate the most dreaded error in C# System.NullReferenceException
or simply Object reference not set to an instance of an object
. The issue occurs most of the times if null reference checks are not properly handled before using an unassigned object reference. Null reference checks are time consuming code and also leads to lot of programming. They can be done before passing parameters to a method, concatenating strings for display /messages or assigning it to local variables.
Problem Statement
Lets take a simple example where we need to display visitor details. I have created a console application for this example but this error can happen in any application type where C# code is used.
Here Visitor is a class having 2 properties
- Name
- Contact Details
Contact Details is also a class having 2 properties
- MobileNo
- EmailAddress
class Visitor
{
public string Name { get; set; }
public ContactDetails ContactDetails { get; set; }
}
class ContactDetails
{
public string Mobile { get; set; }
public string EmailAddress { get; set; }
}
Now let's enter a Visitor Named Yash who has just provided his Mobile Number
The below code will throw System.NullReferenceException
since ContactDetails is null and we are trying to access its properties using Visitor Object Reference (visitorObj)
class Program
{
static void Main(string[] args)
{
Visitor visitorObj = new Visitor();
visitorObj.Name = "Yash";
visitorObj.ContactDetails = null;
Console.WriteLine(String.Format("Name {0} Mobile No {1} Email Address {2}", visitorObj.Name, visitorObj.ContactDetails.Mobile, visitorObj.ContactDetails.EmailAddress));
Console.ReadLine();
}
}
Solution 1 (without Elvis)
To avoid this error, we need to put some null reference checks.
But before that let's analyze how many possibilities there can be in a program which can lead to null reference error
All these conditions may not be required for this program example but it is a good practice to handle them since one may move the code to different assembly/class and that time it would become essential.
- Visitor Object Reference (visitorObj) can be null if no visitor object is created
- visitorObj.Name
- visitorObj.ContactDetails
- visitorObj.ContactDetails.Mobile
- visitorObj.ContactDetails.EmailAddress
So to write a program which can cater all the possibilities mentioned above we need to write multiple if-else loops or use ternary operators. Let's take hybrid approach to reduce code.
class Program
{
static void Main(string[] args)
{
Visitor visitorObj = new Visitor();
visitorObj.Name = "Yash";
visitorObj.ContactDetails = null;
if(visitorObj != null)
Console.WriteLine(String.Format("Name {0} Mobile No {1} Email Address {2}",
visitorObj.Name!=null?visitorObj.Name:null,
visitorObj.ContactDetails != null ? visitorObj.ContactDetails.Mobile !=null? visitorObj.ContactDetails.Mobile :null: null,
visitorObj.ContactDetails != null ? visitorObj.ContactDetails.EmailAddress != null ? visitorObj.ContactDetails.EmailAddress : null : null));
else
Console.WriteLine("The object is not created");
Console.ReadLine();
}
}
But you can see how complicated the above code has become due to nested ternary conditions.
Solution 2 (with Elvis)
So lets see how Elvis operator is going to help us in this
?. operator will first compare the left part of the operator with null if not then will get the right part of the operator
For e.g. val = x?.y
means
if(x!=null){
val=x.y; }
else val = null;
Or
val = (x!=null)?x.y:null ;
So when we substitute Elvis Operator we get the following:-
Visitor visitorObj = new Visitor();
visitorObj.Name = "Yash";
visitorObj.ContactDetails = null;
Console.WriteLine(String.Format("Name {0} Mobile No {1} Email Address {2}", visitorObj?.Name, visitorObj?.ContactDetails?.Mobile, visitorObj?.ContactDetails?.EmailAddress));
Console.ReadLine();
Here string x = visitorObj?.ContactDetails?.Mobile
means
if(visitorObj!=null && ContactDetails !=null)
string x = visitorObj.ContactDetails.Mobile;
or
string x =(visitorObj != null)?(ContactDetails !=null)?ContactDetails.Mobile:null:null;
The above code is much clearner and easy to implement plus it is taking care of all the null reference checks in the application. The Elvis Operator can be very useful and handy to avoid most of the Null Reference Check Errors. The limitation of the Elvis operator can be seen is that it will assign "null" as default value when the left side of the operator is null. Also it does not give any flexibility like if-else wherein you can write code in else part also.
Coding is Simple