Different Ways of using the C# Null Coalescing Operator

The C# Null-Coalescing operator or the ?? operator is a binary operator that returns the left-hand operand if it is not null; otherwise it returns the right operand. It can be used with both nullable and reference types.

Here’s a simple example of using the Null-Coalescing operator

int? i = null;
int j = i ?? 2;
// here the resultant value of j is 2
Here are some additional ways of using the Null-Coalescing operator in your code.

Method 1

string address = homeAddress1 ?? homeAddress2 ?? officeAddress
?? "No Address";

returns the first non-null value in this long expression. This expression returns “No Address” if homeAddress1, homeAddress2 and officeAddress are Null.


Method 2

While converting a Nullable Type to Non-Nullable type, we do an explicit cast to avoid assigning null values to a non-nullable type, as shown below:

int? a = NullType(); // returns nullable int
int b = (int)a;
instead you can avoid the explicit cast using a null-coalescing operator and write:
int? a = NullType();
int b = a ?? 0;

Method 3

private IList<Person> person;
public IList<Person> PersonList
{
get
{
return person ?? (person = new List<Person>());
}
}
Typical usage of the null-coalescing operator in a lazy instantiated private variable.


Method 4

string conn = Connection["TestMachineStr1"]
?? AppConnection["ProdMachineStr2"]
?? DefaultConnection["DefaultConn"];

Accessing NameValueCollections and choosing the first non-null value.

Note: The Null-Coalescing operator is useful but may sometimes be an overkill, especially when developers use it to flaunt their coding skills. I sometimes choose ‘understandable code’ over ‘terse code’, focusing on the intent.

Feel free to use the comments section to demonstrate how you have used the null-coalescing operator in your projects.





About The Author

Suprotim Agarwal
Suprotim Agarwal, Developer Technologies MVP (Microsoft Most Valuable Professional) is the founder and contributor for DevCurry, DotNetCurry and SQLServerCurry. He is the Chief Editor of a Developer Magazine called DNC Magazine. He has also authored two Books - 51 Recipes using jQuery with ASP.NET Controls. and The Absolutely Awesome jQuery CookBook.

Follow him on twitter @suprotimagarwal.

9 comments:

al said...

You can also use ?? to null coalesce amongst classes sharing the same base class. Normally this wouldn't compile but there is a work around:

class Animal{}

class Bear: Animal{}

class Tiger: Animal{}

...

Animal MyAnimal{
get{ return this.Bear ?? (Animal) this.Tiger; }
}

Anonymous said...

It should be noted that method 1 will get you into trouble when any of the addresses is String.Emtpy,
Because well, String.Emtpy != null.

I have made an Extension method to the string class: IfNullOrEmpty.

Method 1 would translate to:
string address = homeAddress1
.IfNullOrEmpty(homeAddress2)
.IfNullOrEmpty(officeAddress)
.IfNullOrEmpty("No Address");

Still, if you would be inclined to write code like this, I would advise you to rethink your strategy.

Suprotim Agarwal said...

Point accepted and thank you. However it is not about adopting a coding strategy. I agree there is a check needed to see if the string is empty before using this code.

The article purely focuses on different ways to use the null-coalesce operator and I just showed one way. That extension method of yours is useful.

Anonymous said...

Is method3 is thread-safe?

Unknown said...

The behaviour in method 2 is changed by the replacement code. The origional code could result in a NullReferenceException whereas the replacement results in 0.

Method 1 and 4 are just variations on the same thing, you should just put the code next to eachother. Method 4 just indicates you could use it for configuration options.

@Zagrebelin:
Method 3 is not threadsafe, but most samples are not threadsafe. For threadsafety never try to be overly smart as the runtime is able to reverse and optimize code in strange ways. For threadsafety and code optimization (Release mode) you always need memory bariers (locks etc.). Every other way to be smart about it almost always fails as there are many pitfalls when te JIT-engine starts optimizing.
See slide 32 of http://www.cs.umd.edu/class/spring2006/cmsc132/Slides/JMM06.pdf as almost all statements on java also apply to the .Net runtime.

Regards,
Jelle

Unknown said...

The behaviour in method 2 is changed by the replacement code. The origional code could result in a NullReferenceException whereas the replacement results in 0.

Method 1 and 4 are just variations on the same thing, you should just put the code next to eachother. Method 4 just indicates you could use it for configuration options.

@Zagrebelin:
Method 3 is not threadsafe, but most samples are not threadsafe. For threadsafety never try to be overly smart as the runtime is able to reverse and optimize code in strange ways. For threadsafety and code optimization (Release mode) you always need memory bariers (locks etc.). Every other way to be smart about it almost always fails as there are many pitfalls when te JIT-engine starts optimizing.
See slide 32 of http://www.cs.umd.edu/class/spring2006/cmsc132/Slides/JMM06.pdf as almost all statements on java also apply to the .Net runtime.

Regards,
Jelle

Anonymous said...

Jelle Hissink - OMG did you just read a book and need to flaunt it? That is not a contrib. but just plane amateuris, speaking for the sake of it. Zip it up!

Jelle Hissink said...

@Anonymous (whoever you may be)
Sorry if I bother you... but you don't contrib even less.

I have developed heavy multithreaded/multicore applications for a long time now and it is just a somewhat long answer to Zagrebelin's question.

The other remarks are just because I felt like it like you did your remark.

Regards,
Jelle

Suprotim Agarwal said...

For those who are worried about empty strings in Method 1, you can also adopt this piece of code if it helps

string address = new[]{ homeaddr, homeaddr2, offaddr, "No address" }.First(a => !string.IsNullOrEmpty(a));