当我试图了解 Round 实际上做了什么时,我最终查看了一个简单控制台程序的 IL(从 C# .NET 4.5 编译器发出):
.maxstack 2
.locals init (float64 V_0,
float64 V_1)
IL_0000: ldc.r8 2.0001232314135344
IL_0009: stloc.0
IL_000a: ldloca.s V_0
IL_000c: call instance string [mscorlib]System.Double::ToString()
IL_0011: call void [mscorlib]System.Console::WriteLine(string)
IL_0016: ldloc.0
IL_0017: ldc.i4.5
IL_0018: call float64 [mscorlib]System.Math::Round(float64,
int32)
IL_001d: stloc.1
IL_001e: ldloca.s V_1
IL_0020: call instance string [mscorlib]System.Double::ToString()
IL_0025: call void [mscorlib]System.Console::WriteLine(string)
IL_002a: ret
Run Code Online (Sandbox Code Playgroud)
我注意到有关 IL_001d 和 IL_001e 的说明。它们对我来说似乎是多余的,将值存储在本地并在此之后立即加载相同的值。删除它们并重新组装 IL 给我一个 NullReferenceException,所以我猜它有一定的意义。但我想不通。
那么 NullReferenceException 是从哪里来的呢?为什么编译器会发出这两条指令?没有比上面给出的更多的 IL,当然除了一些元。
ldloca将变量的地址加载到堆栈上(不是变量本身)。所以,这两个命令不是相反的:stloc.1弹出由 返回的变量值Math::Round,并压入调用所需ldloca.s的 堆栈地址。V_1Double::ToString
| 归档时间: |
|
| 查看次数: |
363 次 |
| 最近记录: |