Resolving null values in C#
August 24, 2017 1 Comment
Say you have a method which accepts a string parameter. The method may need to handle null values in some way. One strategy is to validate the parameter and throw an exception:
private static string Resolve(string input)
{
if (input == null) throw new ArgumentNullException("Input");
.
.
.
}
Another strategy is to provide some default value with an if-else statement:
private static string Resolve(string input)
{
string res;
if (input == null)
{
res = "Empty input string";
}
else
{
res = input;
}
return res;
}
This can be greatly simplified with the ternary operator:
private static string Resolve(string input)
{
string res = input == null ? "Empty input string" : input;
return res;
}
An even simpler solution is by using the null-coalescing operator ?? :
private static string Resolve(string input)
{
string res = input ?? "Empty input string";
return res;
}
This statement is equal to the first if-else solution but it’s a lot more elegant and concise.
You can use this technique with any nullable type of course, not just strings. The ?? operator can even be chained:
private static string Resolve(string input)
{
string intermediate = null;
string res = input ?? intermediate ?? "Empty input string";
return res;
}
Here res will be “Empty input string” if both ‘input’ and ‘intermediate’ are null. If ‘input’ is null and ‘intermediate’ is ‘hello world’ then ‘res’ will be ‘hello world’.
In C# 6
C# 6 has a new syntax for testing for null values. Let’s build an 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.
Pingback: Resolving null values in C# | Elliot Balynn's Blog