【问题标题】:Does null coalescing operator cache the result in c#空合并运算符是否在c#中缓存结果
【发布时间】:2015-06-15 18:42:30
【问题描述】:

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

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

【问题讨论】:

  • 以上两个是很好的答案,解释?? .请看一看。
  • @Mukund - 都解释了合并运算符的作用,但不回答表达式是否计算一次\两次的问题。 (hamid 在第二个中的回答似乎表明了两次,但我不认为这是正确的,因为他只是想解释它的作用,而不是 IL 中生成的内容).. 测试使用起来很容易一个静态计数器,但我宁愿听专家说 ;-)
  • @arviman 点。我只是把你的问题读成“我知道 X 是真的,那么 X 是假的吗?”其中 X 是假的,所以问题的开头句是一个反事实假设。我意识到您的问题是反问的,但无论如何我都会回答:我可能只是问“?? 运算符的左操作数是否在其结果为非空时执行了两次”,尽管有些冗长。但那是在整个讨论之后。我同意,从头开始提出问题可能很困难。

标签: c# null-coalescing-operator


【解决方案1】:

好吧,如果“缓存”是指将其存储在临时变量中,那么可以。

这个结构:

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

可以认为等价于:

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

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

所以回答你的具体问题:

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

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

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

结果:

  1. 评估first()
  2. 如果first() 评估为null,则评估second()
  3. 如果second() 也评估为null,则评估third()
  4. 如果以上所有都评估为null,则最终评估fourth

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


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

var result = first?.second?.third;

这是基本的. 处理,即。它将读取firstsecond 成员,然后是secondthird 成员,但它将在第一个null 处停止,并且还将确保每个步骤只评估一次:

(obj as IDisposable)?.Dispose();

obj as IDisposable 只会评估一次。

TryGetObjectToSave()?.Save();

只会调用一次TryGetObjectToSave(),如果它返回一些东西,就会调用那个东西上的Save()方法。

【讨论】:

    猜你喜欢
    • 2010-10-03
    • 2011-02-13
    • 2011-02-20
    • 2011-06-19
    • 2014-03-10
    • 2011-06-26
    • 2012-09-23
    • 2010-12-25
    • 1970-01-01
    相关资源
    最近更新 更多