Does null coalescing operator cache the result in

2020-04-02 17:58发布

问题:

I know that doing (myValue ?? new SomeClass()) is similar to (myValue == null ? new SomeClass() : myValue)

But out of curiosity, is there any performance benefit when I call a function, say (getResult() ?? new SomeClass()). Will getResult() get executed twice? It seems unintuitive since I've specified the method call only once.

回答1:

Well, if by "caching" you mean storing it in a temporary variable, then yes.

This construct:

var result = (getResult() ?? new SomeClass());

can be thought of to be equivalent to this:

var <temp> = getResult();
if (<temp> == null)
    <temp> = new SomeClass();
result = <temp>;

This also tells you that the second part, the operand after ?? isn't executed at all if the first operand is not null.

So to answer your concrete questions:

  1. Each operand is evaluated at most once
  2. The second operand is only evaluated if the first one evaluates to null

Note also that you can chain these:

var result = first() ?? second() ?? third() ?? fourth();

Which results in:

  1. Evaluates first()
  2. If first() evaluated to null, evaluates second()
  3. If second() evaluated to null as well, evaluates third()
  4. If all of the above evaluated to null, finally evaluates fourth

The result is the first (no pun intended) non-null value returned.


This type of code is about to get even better in new C# with the new ?. operator:

var result = first?.second?.third;

This is basic . handling, ie. it will read the second member of first, and then the third member of whatever second is, but it will stop at the first null, and will also make sure to evaluate each step only once:

(obj as IDisposable)?.Dispose();

obj as IDisposable will only evaluate once.

TryGetObjectToSave()?.Save();

Will only call TryGetObjectToSave() once, and if it returns something, the Save() method on that something will be called.