【问题标题】:Compound Assignment in .Net.Net 中的复合赋值
【发布时间】:2020-12-07 01:03:48
【问题描述】:

我想知道 .Net 中是否曾经或现在仍然是这种情况。

使用 exp += val 代替 exp = exp + val。由于 exp 可以是 任意复杂,这可能会导致大量不必要的工作。这 强制 JIT 评估 exp 的两个副本,很多时候这是 并不需要。第一条语句可以优化得比 其次,因为 JIT 可以避免两次评估 exp。

这来自 codeproject 中的一篇古老的文章。

cpp中还有一个:

但是,复合赋值表达式并不等同于 扩展版本,因为复合赋值表达式计算 expression1 只有一次,而扩展版本计算 expression1 两次:在加法运算中和在赋值中 操作。

【问题讨论】:

  • 我认为这可能是指在 int 属性上使用 += 而不是本地或字段。
  • 你有codeproject文章的链接或wayback-machine副本吗?我想知道作者是谁,因为从历史上看,有很多非专家在 CodeProject 上宣称完全不正确的信息。 C# 规范是怎么说的?
  • @Dai,我在 c# 规范中找不到
  • 我认为这需要一个语言标签,因为+= 是 C# 和 VB.NET 中的运算符。 C# documentation 表示“x += y 等同于 x = x + y,除了 x 只评估一次”,但我不明白分配给 x 需要如何评估它(再次)。也许这只是做collection[index] += valueSomeObject.SomeMethod().SomeProperty += value之类的优化;否则,它只是简写。

标签: c# .net optimization language-lawyer compound-assignment


【解决方案1】:

是的,它曾经是,现在仍然是 .NET 中的最佳实践。要添加 4 的图像

myObject.MyExpensiveMethod().MyProperty

显然你不想这样做:

myObject.MyExpensiveMethod().MyProperty = 
    myObject.MyExpensiveMethod().MyProperty + 4;

因为它调用了两次昂贵的方法,而+= 只调用了一次。你可以这样做:

var temp = myObject.MyExpensiveMethod();
temp.MyProperty = temp.MyProperty + 4;

较少昂贵,但这样做最便宜:

myObject.MyExpensiveMethod().MyProperty += 4;

因为昂贵的方法只被调用一次。

另一种情况是当您使用具有副作用的方法时,您只想调用一次:

myFactory.GetNextObject().MyProperty += 5;

你_肯定不会这样做

myFactory.GetNextObject().MyProperty = myFactory.GetNextObject().MyProperty + 5;

您可以再次使用临时变量,但复合赋值运算符显然更简洁。

当然,这些都是极端情况,但养成这种习惯并不是一个坏习惯。

【讨论】:

  • @DanielB 为什么myObject.MyExpensiveMethod().MyProperty 不是您意义上的表达方式?
  • @DanielB 这篇文章是否在谈论某种文字 <Expression<T>?为myObject.MyExpensiveMethod().MyProperty 创建一个表达式很简单,但结果是一样的。
  • @DanielB 如果您专门谈论简单的int x = 123; x += value; 场景,那么问题中不包含此类要求。然而,其中包含的是“由于 exp 可以任意复杂”的引用,我认为 myObject.MyExpensiveMethod().MyProperty 肯定符合“任意复杂”的条件。您确实意识到,在您引用的第一个文本中,“exp”是“表达式”的缩写,而不是简单地说,一个恰好被命名为 exp? 的局部变量
猜你喜欢
  • 2021-04-24
  • 1970-01-01
  • 1970-01-01
  • 2012-01-21
  • 2018-09-30
  • 1970-01-01
  • 2011-11-16
  • 2020-12-01
  • 1970-01-01
相关资源
最近更新 更多