其他答案暗示了这一点,我赞同 C++ 的建议,将其视为“一件坏事”,但“简单”的解决方法是:
int x = 0;
x = Increment(ref x) + x;
因为 C# 确保从左到右评估表达式*,所以这符合您的预期。
*引用 C# 规范的“7.3 运算符”部分:
表达式中的操作数从左到右计算。例如,在 中F(i) + G(i++) * H(i)
,F
使用 的旧值调用i
方法,然后使用 的旧值G
调用方法i
,最后H
使用 的新值调用方法i
。这与运算符优先级分开且无关。
请注意,最后一句话的意思是:
int i=0, j=0;
Console.WriteLine(++j * (++j + ++j) != (++i + ++i) * ++i);
i = 0; j = 0;
Console.WriteLine($"{++j * (++j + ++j)} != {(++i + ++i) * ++i}");
i = 0; j = 0;
Console.WriteLine($"{++j} * ({++j} + {++j}) != ({++i} + {++i}) * {++i}");
输出这个:
真
5 != 9
1 * (2 + 3) != (1 + 2) * 3
最后一行可以“信任”为与前两个表达式中使用的值相同的值。IE 即使在乘法之前执行加法,由于括号,操作数已经被计算。
请注意,将其“重构”为:
i = 0; j = 0;
Console.WriteLine(++j * TwoIncSum(ref j) != TwoIncSum(ref i) * ++i);
i = 0; j = 0;
Console.WriteLine($"{++j * TwoIncSum(ref j)} != { TwoIncSum(ref i) * ++i}");
i = 0; j = 0;
Console.WriteLine($"{++j} * {TwoIncSum(ref j)} != {TwoIncSum(ref i)} * {++i}");
private int TwoIncSum(ref int parameter)
{
return ++parameter + ++parameter;
}
仍然完全一样:
真
5 != 9
1 * 5 != 3 * 3
但我仍然宁愿不依赖它:-)