Tij*_*ohn 4 c# boxing unboxing value-type
比方说,我在c#中有以下代码
int x = 0;
x.ToString();
Run Code Online (Sandbox Code Playgroud)
这内部是否做了拳击x?有没有办法从视觉工作室看到这种情况?
这是您的代码生成的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();
Run Code Online (Sandbox Code Playgroud)
不会令人惊讶地导致拳击:
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以避免装箱.具体来说,一个约束 callvirt被发出:
如果thisType是一个值类型而thisType实现了方法,那么ptr将被未修改地传递为调用方法指令的'this'指针,用于通过thisType实现方法.
如果thisType是一个值类型而thisType没有实现方法,则ptr被解除引用,装箱,并作为'this'指针传递给callvirt方法指令.
如果要在调用时避免装箱Equals,GetHashCode并且ToString在值类型上需要覆盖这些方法.
在这种特定情况下,您使用的是System.Int32(an int).这种类型的重新定义ToString,Equals以及GetHashCode,所以没有拳击.
如果您使用struct的是不重新定义ToString什么你必须是一个constrained callvirt到System.Object.ToString().约束的定义:
当callvirt方法指令以约束thisType作为前缀时,指令执行如下:
- 如果thisType是一个值类型而thisType实现了方法,那么ptr将被未修改地传递为调用方法指令的'this'指针,用于通过thisType实现方法.
- 如果thisType是一个值类型而thisType没有实现方法,则ptr被解除引用,装箱,并作为'this'指针传递给callvirt方法指令.
所以如果值类型实现ToString没有拳击,如果它没有实现它就有拳击...有趣.我不知道.
对于非虚拟方法GetType(),在System.Object值类型中定义的方法始终是框.刚刚测试过:
5.GetType();
Run Code Online (Sandbox Code Playgroud)
产生IL代码:
IL_0001: ldc.i4.5
IL_0002: box [mscorlib]System.Int32
IL_0007: call instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
655 次 |
| 最近记录: |