为什么以下代码的结果是 x = y = z = 1 ?
int x = 0, y= 0, z = 0;
x += y += z += 1;
Console.WriteLine("{0} {1} {2}", x, y, z);
答案 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
的值)。