所谓装箱就是 装箱是将值类型转换为 object 类型或由此值类型实现的任一接口类型的过程。而拆箱就是反过来了。不少人可能都知道这一点,可是是否真的就很了解boxing和unboxing了呢?能够看下下面一段代码,里面发生了几回装箱过程?html
public static void Main(string[] args) { Int32 v = 5; Object o = v; v = 123; Console.WriteLine(v+" , "+(Int32)o); }
很多人可能认为只有一次装箱,其实里面发生了3次装箱过程,是否是很意外!
第一次很明显,就在 Object o = v;时发生。
第二次和第三次都是发生在Writeline()方法里面了。调用此方法是要求获取一个String对象,可是,当前没有字符串对象,它只有三个数据项能够用:一个未装箱的Int32值类型的实例(v),一个String(是一个引用类型),以及一个已经装箱的Int32值类型实例的引用(o),它须要转化成一个未装箱Int32的值类型。因此必须以某种方式对这些数据进行合并,以建立一个String。spa
为了建立String,C#编译器会生成代码来调用String对象的静态方法Concat。这个方法有好几个重载版本,因为须要把三个数据项链接起来,因此编译器选择的是:code
public static string Concat( Object arg0, Object arg1, Object arg2 )
为第一个参数arg0传入的是值类型v,但arg0是一个Object,因此必须对v进行装箱,并将已经装箱的v的地址传给arg0。为arg1参数传递的是一个" , ",它本质上是一个String对象的引用,无需装箱。最后对于arg2,o(一个Object对象的引用)会转换成一个Int32,这要求执行一次拆箱操做(但不紧接着执行一次复制操做),从而获取在已装箱Int32中未装箱的Int32的地址。这个未装箱的Int32实例必须再次装箱,并将新的已装箱实例的地址传给Concat的arg2参数。htm
而后Concat调用指定的每一个对象的TosSring方法,并链接每一个对象的字符串表示,最终由WriteLine方法显示出来。对象