多复合赋值运算符?

时间:2018-02-07 07:34:23

标签: c#

为什么以下代码的结果是 x = y = z = 1

int x = 0, y= 0, z = 0;
x += y += z += 1;
Console.WriteLine("{0} {1} {2}", x, y, z);

3 个答案:

答案 0 :(得分:1)

赋值语句实际上计算为值。它评估的值等于赋值语句的右侧。

因此x = 5;评估为5

现在让我们解读一下:

x += y += z += 1;

首先,我们替换速记+=以使事情更清晰(注意赋值运算符是右关联的):

x += y += (z = z + 1)
x += (y = y + (z = z + 1))
x = x + (y = y + (z = z + 1))

现在,我们评估!请记住,作业会评估右侧的值!

x = x + (y = y + (z = z + 1))
x = x + (y = y + (z = 1))
x = x + (y = y + 1) // z is now 1
x = x + (y = 1)
x = x + 1 // y is now 1
x = 1
// x is now 1

答案 1 :(得分:0)

由于:

  • z (0)增加1(因此: 0 + 1 = 1
  • y (0)增加z,这是上一个操作(z += 1 -> 1)的结果,因此y + z = 0 + 1 = 1
  • x (0)增加y,这是上一个操作(y += z -> 1)的结果,因此x + y = 0 + 1 = 1

即使操作是链接的,这并不意味着它们会被一次性评估。它们总是按顺序从右到左执行,只要它们的操作符具有相同的优先级(这是这种情况)。将代码拆分为evaluation order之后的多行并简化符号可能会更好地了解正在发生的事情:

Int32 x = 0;
Int32 y = 0;
Int32 z = 0;

z = z + 1; // z = 0 + 1 = 1
y = y + z; // y = 0 + 1 = 1
x = x + y; // x = 0 + 1 = 1

答案 2 :(得分:0)

由于您的所有运算符具有相同的优先级,因此您需要一些执行顺序。正如MSDN所示,+= - 运算符的顺序是从从右到左。相比之下,3 + 4 + 5将首先评估3 + 4,然后将5添加到结果中,因为+ - 运算符从左到右评估。< / p>

在你的例子中也是如此。首先z += 1将评估为一个。此结果(不是z本身)将传递给下一个+= - 运算符,因此您将获得y += 1,其自身的计算结果为1,并再次分配给运算符+=

运算符与简单的方法调用基本上没什么区别,因为您可以通过其签名来指示:

public static int operator += (int c1, intc2) { ... }

所以你要做的就是用前面的调用结果调用那个“方法”:

int.CallAssignPlus(ref x, int.CallIassgnPlus(ref y, int.CallAsignPlus(ref z, 1)));

当然,该代码并不是它实际上如何转换为IL,但它显示了它是如何工作的。

所以这里最重要的不是事实,你有变量分配给任何东西,而是甚至分配的结果是一个表达式,可以在任何其他语句中使用。说过这个z +=1只是一个有价值的陈述。因此,z不会传递给y,而是传递给该语句的值(但是它等于z的值)。