c# - 分配中意外的后增量行为

标签 c# expression

你能帮我理解为什么变量 a 在第一种情况下没有递增,而在第二种情况下却递增吗?

案例 1:

int a = 10;            
a = a++;
Console.WriteLine(a); //prints 10

案例 2:

int a = 10;                        
int c = a++;
Console.WriteLine(a); //prints 11

我已经回答了其他类似的问题,但找不到任何细节。

更新 1:我认为程序的流程如何

案例 1:

1. 'a' is assigned 10
2. 'a' is assigned 10 before increment happens
3. 'a' is incremented by 1 (Why doesn't this step affect the final value of 'a'?)
4. 'a' is printed --> 10

案例 2:

1. 'a' is assigned 10
2. 'c' is assigned 10 before 'a' is incremented
3. 'a' is incremented by 1 (Why does the increment of 'a' work here?)
4. 'a' is printed --> 11

更新 2:感谢所有的回答,我想我已经理解了,如果我错了请纠正我。

案例 1:

1. `a` is assigned 10
2. Compiler evaluates `a++`, stores old value 10 and new value 11 as well. Since it's a post increment operation, assigns the old value to `a`. What i thought was, compiler would assign the old value 10 first and evaluate the `++` operation later. This is where i was wrong, compiler evaluates the RHS beforehand and assigns the value based on the operator.
4. 'a' is printed --> 10

案例 2:

1. `a` is assigned 10
2. Compiler evaluates `a++`, stores old value 10 and new value 11 as well. Since it's a post increment operation, assigns the old value to `c` but value of `a` is preserved with `11`.
4. 'a' is printed --> 11

最佳答案

对我而言,了解某些行为的最佳方式是检查生成的 IL。在你的第一种情况下是

IL_0001:  ldc.i4.s    0A // stack: 10
IL_0003:  stloc.0     // a = 10, stack: empty
IL_0004:  ldloc.0     // stack: 10
IL_0005:  dup         // stack: 10, 10
IL_0006:  ldc.i4.1    // stack: 10, 10, 1
IL_0007:  add         // stack: 10, 11
IL_0008:  stloc.0     // a = 11, stack: 10
IL_0009:  stloc.0     // a = 10, stack: empty
IL_000A:  ldloc.0     // stack: 10
IL_000B:  call        System.Console.WriteLine

您可以看到原始值仍然卡在堆栈上,因此创建的 11 最后被覆盖了。

让我试着用通俗易懂的话来解释一下。

当您为变量赋值时 (a = a++),赋值的整个右侧首先被计算以保证正确的值,就是这样。所以没有什么比你得到 10,应用程序继续并在你执行下一行时增加值。

现在,将后递增想象成某人,他首先递增一个值,但给了你他的世界,你将从表达式中取回原始值。现在你应该明白为什么 11 被覆盖了。增量在前,最后,您将获得 promise 的原始值(正如 IL 所证明的那样)。

关于c# - 分配中意外的后增量行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27996608/

相关文章:

asp.net-mvc - 向表达式添加断行

scala - Spark Scala 聚合中的展开表达式

C# Controller 行为根据变量名改变

c# - 如何检测 Xamarin Forms 选项卡式页面点击 - iOS?

c# - 在 F# 中返回具有名称的元组

reporting-services - IF的SSRS表达式,然后其他

c - 三元表达式错误

javascript - 用于验证最后一位数字的正则表达式

c# - 以表格形式查看 XML 数据

c# - 使用 C# 中的部分类将 WinForm 的一些控件移动到另一个 WinForm