null合并运算符是否将结果缓存在c#中

arv*_*man 10 c# null-coalescing-operator

我知道这样做(myValue ?? new SomeClass())很像(myValue == null ? new SomeClass() : myValue)

但出于好奇,当我调用一个函数时,是否有任何性能优势 (getResult() ?? new SomeClass()).会getResult()被执行两次吗?这似乎不直观,因为我只指定了一次方法调用.

ang*_*son 15

好吧,如果通过"缓存"你的意思是将它存储在一个临时变量中,那么是的.

这个结构:

var result = (getResult() ?? new SomeClass());
Run Code Online (Sandbox Code Playgroud)

可以被认为是等同于:

var <temp> = getResult();
if (<temp> == null)
    <temp> = new SomeClass();
result = <temp>;
Run Code Online (Sandbox Code Playgroud)

这也告诉你第二部分,??如果第一个操作数不是,则根本不执行操作数null.

那么回答你的具体问题:

  1. 每个操作数最多只评估一次
  2. 仅当第一个操作数的计算结果为止时,才会计算第二个操作数 null

另请注意,您可以链接这些:

var result = first() ?? second() ?? third() ?? fourth();
Run Code Online (Sandbox Code Playgroud)

结果如下:

  1. 评估板 first()
  2. 如果first()评估为null,则评估second()
  3. 如果second()进行评估null,则进行评估third()
  4. 如果以上所有评估结果null,最后进行评估fourth

结果是返回的第一个(无双关语)非空值.


这种类型的代码即将在使用new ?.运算符的新C#中变得更好:

var result = first?.second?.third;
Run Code Online (Sandbox Code Playgroud)

这是基本.处理,即.它将读取second成员first,然后third成为任何成员second,但它将在第一步停止null,并且还将确保仅评估每个步骤一次:

(obj as IDisposable)?.Dispose();
Run Code Online (Sandbox Code Playgroud)

obj as IDisposable 只评估一次.

TryGetObjectToSave()?.Save();
Run Code Online (Sandbox Code Playgroud)

只调用TryGetObjectToSave()一次,如果它返回一些东西,Save()就会调用该方法.