关于.net中值类型的方法调用
最近在看关于box和unbox的内存分配问题,发现一旦值类型调用了基类的方法或接口的时候就会发生装箱操作。因为基类型的方法或接口必须通过TypeHandle获得。由此引出了一个问题。若所执行的方法并不是基类型的虚方法而是值类型自己定义的方法时,CLR又是如何找到值类型的方法代码呢?
对于引用类型,CLR可以通过在堆中的TypeHandle找到其对应的MethodTable,进而定位到此类型的方法代码,编译并执行之。然而值类型是分配在栈上,并没有TypeHandle,它是如何找到方法表的?
。。。
public Struct MyStruct
{
private int a;
private int b;
public void MyMethod()
{
...
}
}
public static void Main()
{
MyStruct m=new MyStruct();
m.ToString();//由于是ValueType的方法,不用装箱。
m.GetType();//Object的方法,所以装箱了。
m.MyMethod();//此处不会装箱,但如何找到方法表?
}
IL:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// 代码大小 36 (0x24)
.maxstack 1
.locals init ([0] valuetype ConsoleApplication2.MyStruct m)
IL_0000: nop
IL_0001: ldloca.s m
IL_0003: initobj ConsoleApplication2.MyStruct
IL_0009: ldloca.s m
IL_000b: constrained. ConsoleApplication2.MyStruct
IL_0011: callvirt instance string [mscorlib]System.Object::ToString()
IL_0016: pop
IL_0017: ldloc.0
IL_0018: box ConsoleApplication2.MyStruct
IL_001d: call instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
IL_0022: pop
IL_0023: ret
} // end of method Program::Main