int tempi = 1; object o = tempi; double tempd = (double) o;
编译时能够经由历程,但运行时却报以下毛病:
System.InvalidCastException: 指定的转换无效。
这是由于,当对一个对象举行拆箱时,转型的效果必需是它本来未装箱的范例。此处必需先转换为int范例,才再转换为double范例。其准确花样以下:
int tempi = 32; object o = tempi; double tempd = (double)(int) o;
在.NET框架中,装箱(boxing)一般由以下三步构成:
1.从托管堆中为新生成的援用范例对象分派内存。分派的内存大小为被装箱的值范例实例自身的大小,再加上为新生成的援用范例增加的一个要领表指针和一个SyncBlockIndex。
2.将值范例实例的字段拷贝到托管堆上新分派对象的内存中。
3.返回托管堆中新分派对象的地点。如许值范例实例也变成了一个援用范例对象。
而拆箱(unboxing)历程则以下:
1.假如要拆箱的对象为null,将会抛出一个NullReferenceException非常。
2.假如该援用指向的对象不是一个希冀的值范例的已装箱对象,则拆箱失利,并抛出一个InvalidCastException非常(如本文刚开始的部份)。
3.一个指向包含在已装箱对象中值范例部份的指针被返回。该指针指向的值范例关于援用范例对象一般所具有的附加成员(即一个要领表指针和一个SyncBlockIndex)一窍不通。实际上,该指针指向的是已装箱对象中的未装箱部份(Microsoft.NET 框架程序设计<修订版>)。
关于第3点,能够运用上面的例子来协助明白。起首定义值范例变量tempi,它在内存中占用4个字节,装箱以后,其变成援用对象的同时,增加了一个要领表指针和一个SyncBlockIndex。关于援用范例而言,只须要传一个“援用范例”的地点,就能够获得其值、要领表指针和SyncBlockIndex。在拆箱时,通报的是其“值”的地点(未装箱的部份),即一个“int(Int32)范例”的地点(援用),它只允许读4个字节。而double范例是8个字节,因而隐式的转换是会报错的,须要先将其转换成int范例后,才再转换为double范例。
更多.NET 中的装箱与拆箱完成历程相干文章请关注ki4网!