Usage of ?? operator (null-coalescing operator)

210 views Asked by At

I use ?? operator very heavily in my code. But today I just came across a question.

Here the code which I use for ?? operator

private List<string> _names;
public List<string> Names
{
    get { return _names ?? (_names = new List<string>()); }
}

But in some locations I have seen this code as well.

private List<string> _names;
public List<string> Names
{
    get { return _names ?? new List<string>(); }
}

What is real difference between these codes. In one I am assigning _names = new List() while in other I am just doing new List().

4

There are 4 answers

2
Damith On BEST ANSWER

in second case you not assign _names with new List<string>(), if _names null, every time when you call Names it will create new List<string>(), but in first case new List<string>() create ones.

2
AudioBubble On

The only difference I see is in first case your variable _names will contain a new empty list while in second it does not. In both cases value returned will be same.

0
sandip patil On

It will return same value in both cases but the difference is that if you are accessing _names anywhere in the private functions _names will have an empty list in first case but null value in second case. So the first implementation is correct as per coding standards, in second case you may face issues of null exception.

0
Brian Kintz On

As others have said, the difference is the state of the field _names after the property is retrieved.

Case 1

get { return _names ?? (_names = new List<string>()); }

If _names is null, a new List<string> will be created and assigned. After this, every retrieval of the property Names will return the list that was just created.

Case 2

get { return _names ?? new List<string>(); }

If _names is null, a new List<string> will be returned. In contrast to Case 1, it will NOT be assigned to anything. This means that every time you retrieve Names, a new list will be created and returned.


That being said, you should be very careful with both versions of this code. Assigning values in a get in not necessarily a good thing. It's convenient to lazily instantiate the property value and may be acceptable in cases where you are the only one to use the class, but it's poor style. No user outside your class will expect a get to set anything...that's what the set part of a property is for. In the long run you're pretty much always better off just returning _names and instantiating it in the default constructor. Then it's clear what the code is doing, and you achieve a guaranteed non-null property value.

For the second case, you are far better off returning null and allowing the user to deal with it. Consider the following case, where items is a large collection of objects, each of which contains your property Names and where for whatever reason, Names is always null:

foreach (var item in items.Where(x => x.Names != null)) {
    Console.WriteLine(String.Join(", ", item.Names));
}

If you simply returned null, that entire block would be skipped. However, since you return a new list every time, not only are you running through the entire loop and doing essentially nothing, you're instantiating a new list on each iteration! This can get quite expensive under certain conditions.