C# 6 solves verbose null checks

Downloaded Visual Studio 2015 RC yet? No? What are you waiting for? C# 6.0 has lots to offer! Last time I checked out the brand new nameof keyword. This time I want to look at the Null-Conditional Operator. Something I didn’t know I wanted until playing with it.

Create a new  Console Application, name it NullConditionalOperator and add a class named Person. Copy the following code in Person.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NullConditionalOperator
{
class Person
{

public event EventHandler OnCurrentAddressChanged;
public string Name { get; set; }

private Address _currentAddress;
public Address CurrentAddress
{
get
{
return _currentAddress;
}
set
{
bool isEventRaised = false;

if (_currentAddress != null && !_currentAddress.Equals(value))
{
isEventRaised = true;
}

_currentAddress = value;

if (isEventRaised)
{
OnCurrentAddressChanged?.Invoke(this, new EventArgs());
}

}
}

public Dictionary<string, Address> FormerAddresses { get; set; }

}
}

Add a class named Address and copy the following code into Address.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NullConditionalOperator {

class Address {
public string Street { get; set; }
public int HouseNumber { get; set; }
public string Residence { get; set; }

public bool Validate() {
//Some logic to validate address.
return true;
}

public override string ToString()
{
return string.Format(“{0} {1} at {2}”,
this.Street,
this.HouseNumber,
this.Residence);
}
}

}

Copy the following code in the automatically generated Program.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NullConditionalOperator
{
class Program
{
static void Main(string[] args)
{

Address currentAddress = new Address()
{
Street = “Any street”,
HouseNumber = 1,
Residence = “Anywhere”
};

Dictionary<string, Address> formerAddresses = new Dictionary<string, Address>() {
{ “address1”, new Address() {Street = “Oldstreet”, HouseNumber = 1, Residence = “Somewhere”}},
{ “address2”, new Address() {Street = “Oldeststreet”, HouseNumber = 1, Residence = “Lost”}}
};

Person person = new Person()
{
Name = “John”,
CurrentAddress = currentAddress,
FormerAddresses = formerAddresses
};

Console.WriteLine(string.Format(“#1) I am {0}. My address is {1}”, person.Name, person.CurrentAddress.ToString()));

person.CurrentAddress = null;

Console.WriteLine(string.Format(“#2) I am {0}. My address is {1}”, person.Name, person.CurrentAddress?.ToString()));

person = null;

Console.WriteLine(string.Format(“#3) I am {0}. My address is {1}”, person?.Name, person?.CurrentAddress?.ToString()));

Console.WriteLine(string.Format(“#4) I am {0}. My address is {1}”, person?.Name ?? “Unknown”, person?.CurrentAddress?.ToString() ?? “No address”));

person = new Person()
{
Name = “John”,
CurrentAddress = currentAddress,
FormerAddresses = formerAddresses
};

Console.WriteLine(string.Format(“#5) I am {0}. My most recent former address is {1}”, person.Name, person.FormerAddresses[“address1”].ToString()));

person.FormerAddresses = null;

Console.WriteLine(string.Format(“#6) I am {0}. My most recent former address is {1}”, person.Name, person.FormerAddresses?[“address1”].ToString()));

person.FormerAddresses = formerAddresses;
person.FormerAddresses.Remove(“address1”);
try
{
Console.WriteLine(string.Format(“#7) I am {0}. My most recent former address is {1}”, person.Name, person.FormerAddresses?[“address1”].ToString()));
}
catch (KeyNotFoundException)
{
Console.WriteLine(“#8) This is not valid unfortunatly.”);
}

person.OnCurrentAddressChanged += Person_OnCurrentAddressChanged;

person.CurrentAddress = person.FormerAddresses[“address2”];

Console.ReadKey();

}

private static void Person_OnCurrentAddressChanged(object sender, EventArgs e)
{
Console.WriteLine(“#9) Current address changed!”);
}
}
}

When you run this program you should see the following screen:

2015-05-23 21_21_48-NullConditionalOperator (Running) - Microsoft Visual Studio

Let’s go along the lines shall we?

  1. Simply the value of the Person‘s Name and the CurrentAddress;
  2. Here we see the new Null-Conditional operator in action! CurrentAddress has been set equal to null. If it weren’t for this new operator “?.” the code would’ve crashed with a NullReferenceException;
  3. This line shows it is also a Short-Circuit operator. The reference to the Person instance has also been set to null and we see  “?.” two times. When the evaluation on the variable person fails, CurrentAddress is not even checked anymore;
  4. This line was to show you how well the new Null-Conditional plays along with the Coalesce  function “??” in C# enabling the developer to write very clean and powerfull code;
  5. To set up the next example this line simply shows John’s former address with key “address1” from the FormerAddresses Dictionary;
  6. And here we see after the item with key “address1” is removed how the Null-Conditional operator works with collections. It’s the second way “collection?[index]” in which the Null-Conditional operator can be used; *
  7. This was just a line to see how the operator would react;
  8. Well luckily the app crashed. Remember that this is a solution for the NullReferenceException and not for other exceptions like the KeyNotFoundException;
  9. The Null-Conditional operator is also very usefull to invoke an event handler in a thread safe and clean way. Please may I draw your attention to the setter of the property CurrentAddress in class Person. One line which took several lines before the Null-Conditional operator.
  10. Have you wondered by now what happens to Value types? As you can see in the code when .Count is accessed we need to declare a Nullable type of int to be able to pull it off with the Null-Conditional operator. A small price to pay because with the Coalesce function you can get a meaningfull value (in this case 0) again, instead of checking for null and deciding what needs to be done in case of a null.

So why is this cool?! How many times have you written null checks until your code was actually difficult to read at places? It is actually one of Uncle Bob’s code smells and heuristics (“Don’t Return Null” & “Don’t Pass Null” pages 110/111 from “Clean Code” by Robert C. Martin). Atleast this code smell just got a bit less verbose with the Null-Conditional operator.

Thank you for reading my post. If you liked it, or didn’t like it, have any feedback, or have any questions or additions about the Null-Conditional operator do not hestitate to leave a comment.

* I will never use the Null-Conditional operator on collections though, because in my humble opinion (and in the more valuable opinion of Robert C. Martin) there is no point in making collections null. It is far better to promote clean code when you have a collection with zero items in it. This says a lot more and it keeps a lot of unnecessary null checks out of your code.

Advertisements

About Danny

Bachelor in Commercial ICT MCTS Winforms .NET 2.0 MCTS ASP.NET 3.5 PSM I
This entry was posted in .NET programming, C# 6.0 and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s