valueType.ToString()是否对valueType进行了强制转换?

Tij*_*ohn 4 c# boxing unboxing value-type

比方说,我在c#中有以下代码

int x = 0;
x.ToString();
Run Code Online (Sandbox Code Playgroud)

这内部是否做了拳击x?有没有办法从视觉工作室看到这种情况?

Mar*_*age 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();
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在值类型上需要覆盖这些方法.


xan*_*tos 6

在这种特定情况下,您使用的是System.Int32(an int).这种类型的重新定义ToString,Equals以及GetHashCode,所以没有拳击.

如果您使用struct的是不重新定义ToString什么你必须是一个constrained callvirtSystem.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)