Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any good reasons to not use null-coalescing operator for lazy initialization?

Greetings I was doing some lazy initialization code today, and thought why not use the null-coalescing operator to do this, it is shorter, but then I thought is there any overhead or additional cost to doing it this way.

Below is simplified sample code showing a more common form used for lazy initialization, and then one using null-coalescing operator. They have the exact same results, and appear equivalent. My first thoughts are that after the object has been created there is now an additional assignment of it to itself using ??. Is this a non-issue and the compiler/JIT optimizes this some how, is there something more nefarious going on and you should never do lazy initialization with ??, or it is perfectly safe and no bad mojo can come from it.

private MyLazyObject _lazyObject;

public MyLazyObject GetMyLazyObjectUsingMoreCommonMethod()
{
    if (_lazyObject != null)
        return _lazyObject;

    _lazyObject = new MyLazyObject();

    return _lazyObject;
}

public MyLazyObject GetMyLazyObjectUsingNullCoalescingOpMethod()
{
    _lazyObject = _lazyObject ?? new MyLazyObject();
    return _lazyObject;
}
like image 480
Rodney S. Foley Avatar asked Sep 13 '11 21:09

Rodney S. Foley


People also ask

Why we use null coalescing operator?

operator is known as Null-coalescing operator. It will return the value of its left-hand operand if it is not null. If it is null, then it will evaluate the right-hand operand and returns its result. Or if the left-hand operand evaluates to non-null, then it does not evaluate its right-hand operand.

What is nullable coalescing operator?

The nullish coalescing operator ( ?? ) is a logical operator that returns its right-hand side operand when its left-hand side operand is null or undefined , and otherwise returns its left-hand side operand.

What does it mean in C#?

C# (pronounced "C-sharp") is an object-oriented programming language from Microsoft that aims to combine the computing power of C++ with the programming ease of Visual Basic.


2 Answers

Yes, a little thing called thread safety. The two methods you give are functionally equivalent, so the null coalescing operator is not bad in and of itself, but neither of the approaches you've listed is thread-safe, so if two threads try to call your Get method at the same time, you could end up producing two MyLazyObjects. That may not be a big deal, but it's probably not what you're hoping for.

If you're using .NET 4, just use a Lazy.

private Lazy<MyLazyObject> _lazyObject = 
    new Lazy<MyLazyObject>(() => new MyLazyObject());

public MyLazyObject MyLazyObject {get {return _lazyObject.Value;}}

The code is concise, easy to understand, and thread safe.

like image 112
StriplingWarrior Avatar answered Sep 21 '22 12:09

StriplingWarrior


It is perfectly safe and well defined - and indeed, it means the compiler can just copy the head of the stack (dup) and store once, rather than store-field, load-field.

The only time it is a problem is c# 1.2 (.NET 1.1) where it doesn't exist.

like image 27
Marc Gravell Avatar answered Sep 19 '22 12:09

Marc Gravell