如图5.1所示,所有的类型都与SyStem.Object兼容。然而,因为System.Object是—个多态类型,实例在内存中需要一个对象头,以支持动态方法分发。值类型既没有这个头,也不需要被分配在堆上。CLR允许你在使用对象引用的上下之中,使用值类型(最终是内存),例如,集合或接收System.object作为方法参数的通用函数。为了支持这一点,CLR允许你通过与System.Object兼容的格式,将值类型的实例“克隆”到堆上。这个过程被称为装箱( boxing)(装箱和取消装箱使我们能够统一地来考察类型系统,其中任何类型的值最终都可以按对象处理.类型系统统一化为值类型提供了对象性的优点,并且不会带来不必要的系统开销。例如,对于不需要int值的行为与对象一样的程序,int值只是32位值。对于需要int值的行为与对象一样的程序,就可以使用装箱),并且只要当一个值类型的实例被赋给一个对象引用变量、参数或字段时,这个过程就会发生。
例如,考虑示例5.10的代码。注意,当size的实例被赋给一个对象引用娈量时(本示例中是itf),CLR分配一个基于堆的对象,它实现了被底层值类型(就示例5.10而言,这个“底层值类型’是Size)声明兼容的所有接口(就示例5.10而言,这个“接口”是IAdjustor)。这个装箱的对象是一个独立的拷贝, 并且对它所做的任何政变都不会传递到最初的值类型的实例。然而,只要通过向下强制类型转换操作符,就可能将装箱的对象拷到值类型的实例中,如示例5.10所示.图5.11是装箱和取消装箱的过程。
示制5.10装箱
Public
interface IAdjustor{
Void Adjust();
}
Public struct Size:IAdjustor{
Public void Adjust(){height+=2;weight+=3;}
Public int height;
Public int weight;
}
Static App{
Static void Main(){
Size s=new Size();
Bool truth=s.height==0&&s.weight==0;
s.Adjust();
truth=s.height==2&&s.weigth==3;
IAdjustor itf=s;//装箱
Ift.Adjust()//操作装的副本
Truth=s.height==2&&s.weight==3;
S=(Szie)ift;//取消装箱
Truth=s.height==4&&s.weight==6;
}
}
;