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

时间:2015-04-10 06:27:16

标签: c# null-coalescing-operator

我知道(myValue ?? new SomeClass())(myValue == null ? new SomeClass() : myValue)

类似

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

1 个答案:

答案 0 :(得分:15)

好吧,如果通过“缓存”意味着将其存储在临时变量中,那么是。

这个结构:

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

可以被认为等同于:

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

这也告诉你,如果第一个操作数不是??,那么第二部分,即null之后的操作数根本不被执行。

所以回答你的具体问题:

  1. 每个操作数最多评估一次
  2. 仅在第一个操作数评估为null
  3. 时才评估第二个操作数

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

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

    结果是:

    1. 评估first()
    2. 如果first()评估为null,则评估second()
    3. 如果second()也评估为null,则评估third()
    4. 如果上述所有内容都评估为null,则最终评估fourth
    5. 结果是返回的第一个(没有双关语)非空值。


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

      var result = first?.second?.third;
      

      这是基本的.处理,即。它会读取second的{​​{1}}成员,然后是first成员third,但会在第一个second停止,并且会还要确保只评估每一步:

      null

      (obj as IDisposable)?.Dispose(); 只评估一次。

      obj as IDisposable

      只会调用TryGetObjectToSave()?.Save(); 一次,如果它返回某些内容,则会调用该TryGetObjectToSave()方法。