我想说,我在c#
中有以下代码int x = 0;
x.ToString();
这内部是否有x的拳击? 有没有办法从视觉工作室看到这种情况?
答案 0 :(得分:6)
以下是您的代码生成的IL:
IL_0001: ldc.i4.0 IL_0002: stloc.0 // x IL_0003: ldloca.s 00 // x IL_0005: call System.Int32.ToString
你可以看到没有发生拳击。
另一方面,这段代码
object x = 0;
x.ToString();
不会令人惊讶地导致拳击:
IL_0001: ldc.i4.0 IL_0002: box System.Int32 IL_0007: stloc.0 // x IL_0008: ldloc.0 // x IL_0009: callvirt System.Object.ToString
通常,如果x
的类型不是int
而是任何值类型(struct
),那么您必须覆盖ToString
以避免装箱。具体而言,constrained callvirt
会被发出:
如果thisType是一个值类型而thisType实现了方法,那么ptr将被未经修改地传递为调用方法指令的'this'指针,用于通过thisType实现方法。
如果thisType是一个值类型而thisType没有实现方法,则ptr被解除引用,装箱,并作为'this'指针传递给callvirt方法指令。
如果您想在值类型上调用Equals
,GetHashCode
和ToString
时避免装箱,则需要覆盖这些方法。
答案 1 :(得分:6)
在这种特定情况下,您使用的是System.Int32
(int
)。该类型重新定义了ToString
,Equals
和GetHashCode
,因此没有装箱。
如果您使用的struct
未重新定义ToString
,则constrained callvirt
至System.Object.ToString()
的内容为ToString
。 constrained的定义:
当callvirt方法指令以约束thisType作为前缀时,指令执行如下:
- 如果thisType是一个值类型而thisType实现了方法,那么ptr将被未经修改地传递为调用方法指令的'this'指针,用于通过thisType实现方法。
- 如果thisType是值类型而thisType没有实现方法,那么ptr将被取消引用,盒装,并作为'this'指针传递给callvirt方法指令。
因此,如果值类型实现GetType()
并且如果它没有实现它就有拳击没有装箱......有趣。我不知道。
对于System.Object
中定义的5.GetType();
等非虚拟方法,值类型始终为框。刚刚测试过:
IL_0001: ldc.i4.5
IL_0002: box [mscorlib]System.Int32
IL_0007: call instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
产生的IL代码:
{{1}}