A new way of checking for nulls in C# 6
February 17, 2016 2 Comments
In this post we explored a couple of ways to handle null values in C# 5.
Obviously you can just test whether an object is equal to null:
private static string Resolve(string input) { if (input == null) throw new ArgumentNullException("Input"); . . . }
Also, you can take advantage of the null-coalescing operator:
private static string Resolve(string input) { string res = input ?? "Empty input string"; return res; }
…or the ternary operator:
private static string Resolve(string input) { string res = input == null ? "Empty input string" : input; return res; }
C# 6 has a new syntax for testing for null values. Let’s build a simple object model from the ground up:
- The Address object has a street name and a street number
- The Workplace object has an Address
- The Person object has a Workplace
- The Person object is retrieved from a web service within a GetPersonResponse object
So it’s a relatively deep structure. Here are the relevant classes:
public class Address { public string Street { get; } public int Number { get; } public Address(string street, int number) { Street = street; Number = number; } } public class Workplace { public Address Address { get; } public Workplace(Address address) { Address = address; } } public class Person { public Workplace Workplace { get; } public Person(Workplace workplace) { Workplace = workplace; } } public class GetPersonResponse { public Person Person { get; } public GetPersonResponse(Person person) { Person = person; } }
Now imagine that after acquiring the response from the web service we want to print the Person’s work address. You may be tempted to rush ahead and write:
Console.WriteLine(getPersonResponse.Person.Workplace.Address.Street);
This code can potentially throw the dreaded NullReferenceException for any nullable object:
- getPersonResponse
- Person
- Workplace
- Address
- Street
E.g. if the Person is unemployed then Workplace may be null depending on the business rules we allow:
GetPersonResponse getPersonResponse = new GetPersonResponse(new Person(null)); Console.WriteLine(getPersonResponse.Person.Workplace.Address.Street);
To fully guard against null objects you have to validate each component in the object chain:
if (getPersonResponse != null && getPersonResponse.Person != null && getPersonResponse.Person.Workplace != null && getPersonResponse.Person.Workplace.Address != null && getPersonResponse.Person.Workplace.Address.Street != null) { Console.WriteLine(getPersonResponse.Person.Workplace.Address.Street); } else { Console.WriteLine("No work address available"); }
You’ll probably agree that it is an unhealthy amount of code for a simple task.
C# 6 has a neat shorthand solution for that, here you are:
if (getPersonResponse?.Person?.Workplace?.Address?.Street != null) { Console.WriteLine(getPersonResponse.Person.Workplace.Address.Street); }
Here’s a test object:
GetPersonResponse getPersonResponse = new GetPersonResponse(new Person(new Workplace(new Address("Heaven street", 78))));
Sure enough, the work address “Heaven street” will be printed on the console window.
View all various C# language feature related posts here.
Hello Andras,
you can combine the ? and ?? operator, which is awesome in some cases.
So your last example can be also written with one line (including the else part):
Console.WriteLine(getPersonResponse?.Person?.Workplace?.Address?.Street ?? “No work address available”);
Best regards
Peter
Hi Peter, thanks a lot for your input. //Andras