The null-coalescing operator (??) is one of my favorites, and I see so few developers using it.
MSDN defines the null-coalescing operator as
The ?? operator is called the null-coalescing operator and is used to define a default value for nullable value types or reference types. It returns the left-hand operand if the operand is not null; otherwise it returns the right operand.
Although this is somewhat similar to a conditional operator (sometimes called ‘ternary operator’), it is much more concise.
The null-coalescing operator works with nullable value types and reference types. When I first started with the null-coalescing operator, I often underestimated the usage with empty strings. I think this is very important to discuss, hence this blog post.
Strings
For example:
// conditional operator
string example = null;
string first = example == null ? "default" : example;
// null-coalescing operator
string second = example ?? "default";
In both of these cases, the resulting string will be “default”.
The problem with strings is that the null-coalescing operator only checks against nulls. Code may often return String.Empty instead of nulls. Meaning the following example is not the same.
// conditional operator
string example = string.Empty;
string first = string.IsNullOrEmpty(example) ? "default" : example;
// null-coalescing operator
string second = example ?? "default";
In this example, ‘first’ will be “default” while ‘second’ will be the empty string. This is a situation in which the null-coalescing operator is useful only when a string must not be null but string.Empty is still perfectly valid.
Nullable Value Types
When working with nullable types, the conditional and null-coalescing operators have another alternative when retrieving the underlying value: GetValueOrDefault(). The problem here is that the method returns the value type, not another nullable type.
For example:
int? example = null;
// Conditional operator
int? first = example == null ? 100 : example;
int firstValue = first.Value;
// null-coalescing operator
int? second = example ?? 100;
int secondValue = second.Value;
// GetValueOrDefault()
int third = example.GetValueOrDefault(); // third = 0
int fourth = example.GetValueOrDefault(100); // fourth = 100
Notice the catch in the GetValueOrDefault() example… you don’t have to reassign the nullable and then get the value. This is useful when you only need the value type. Sometimes, you need a default value and the nullable type. In these cases, I still prefer the null-coalescing operator.
Reference types
The null-coalescing operator can be used with reference types to guarantee that properties or methods do not return nulls.
For example:
public List<Person> People
{
get
{
return _people ?? new List<Person>();
}
set { /* something */ }
}
This is definitely a design/coding preference. I’ve experienced environments where developers insist on the importance of the NullReferenceException being thrown in production code. I’ve also experience plenty of environments where exceptional code is properly handled and this construct would rarely, if ever, be useful.
Maybe it is not a well-known operator, or most developers would like code to be lengthier and explicit. In a web development team, I think the null-coalescing operator is very similar to the common JavaScript example of providing a default value using the || operator:
var process = function(val) {
val = val || 100;
/* etc. */
}