Elvis To Rescue From "Object Reference Not Set To An Instance Of An Object"

Introduction

C# 6.0 has introduced a operator which can make coding a bit simpler and less messy. This operator is called as Elvis Operator (not officially though) 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

Let us 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:

  1. Name
  2. Contact Details

Contact Details is also a class having 2 properties:

  1. MobileNo
  2. EmailAddress
  1. class Visitor  
  2. {  
  3.     public string Name { getset; }     
  4.     public ContactDetails ContactDetails { getset; }  
  5. }  
  6.   
  7. class ContactDetails  
  8. {  
  9.     public string Mobile { getset; }  
  10.     public string EmailAddress { getset; }  
  11. }  

Now let's enter a Visitor Named Yash who has just provided his Mobile Number.

The below code will throw System.NullReferenceException since Email Address is null and we are trying to access it using Visitor Object Reference (visitorObj).

  1. class Program    
  2. {    
  3.     static void Main(string[] args)    
  4.     {    
  5.         Visitor visitorObj = new Visitor();    
  6.         visitorObj.Name = "Yash";    
  7.         visitorObj.ContactDetails = new ContactDetails {Mobile="9009009009" };    
  8.   
  9.        Console.WriteLine(String.Format("Name {0} Mobile No {1} Email Address {2}", visitorObj.Name, visitorObj.ContactDetails.Mobile, visitorObj.ContactDetails.EmailAddress));    
  10.         Console.ReadLine();    
  11.        
  12.     }    
  13. }   

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.

  1. Visitor Object Reference (visitorObj) can be null if no visitor object is created
  2. visitorObj.Name
  3. visitorObj.ContactDetails
  4. visitorObj.ContactDetails.Mobile
  5. 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. 

  1. class Program    
  2. {    
  3.     static void Main(string[] args)    
  4.     {    
  5.         Visitor visitorObj = new Visitor();    
  6.         visitorObj.Name = "Yash";    
  7.         visitorObj.ContactDetails = new ContactDetails {Mobile="9009009009" };    
  8.   
  9.         if(visitorObj != null)    
  10.         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 :nullnull,    
  11.             visitorObj.ContactDetails != null ? visitorObj.ContactDetails.EmailAddress != null ? visitorObj.ContactDetails.EmailAddress : null : null));    
  12.          else    
  13.          Console.WriteLine("The object is not created");    
  14.         Console.ReadLine();    
  15.            
  16.     }    
  17. }   

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

  1. if(x!=null){    
  2.         val=x.y; }  
  3.     else val = null;  

Or

  1. val = (x!=null)?x.y:null ; 

So when we substitute Elvis Operator we get the following:

  1. Visitor visitorObj = new Visitor();  
  2.             visitorObj.Name = "Yash";  
  3.             visitorObj.ContactDetails = new ContactDetails {Mobile="9009009009" };  
  4.   
  5.             Console.WriteLine(String.Format("Name {0} Mobile No {1} Email Address {2}", visitorObj?.Name, visitorObj?.ContactDetails?.Mobile, visitorObj?.ContactDetails?.EmailAddress));  
  6.             Console.ReadLine();  

Here visitorObj?.ContactDetails?.Mobile means check visitorObj is not null then ContactDetails is not null and then get Mobile No Property.

The above code is much cleaner and easy to implement plus it is taking care of all the null reference checks in the application. Thus Elvis Operator can be very useful and handy to avoid most of the Null Reference Check Errors. The only 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.