装箱与拆箱的概念

装箱与拆箱的原理和概念

  • “箱”指的是托管堆,装箱即指在托管堆中将在栈上的值类型对象封装,生成一份该值类型对象的副本,并返回该副本的地址,而拆箱即是指返回已装箱值类型在托管堆中的地址(注意:严格意义来说拆箱是不包括值类型字段的拷贝的)。

       #region
       int i =10;
       object o=i   //装箱
       int j=(int)o  //拆箱
    

简介

  • 装箱是将值类型转化为引用类型的过程,拆箱是将引用类型转化为值类型的过程。

装箱的过程为

1 分配内存:在托管堆中分配好内存,内存的大小是值类型的各个字段需要的内存量加上托管堆的所有对象都有两个额外成员 -类型对指针和同步索引 - 所需要的内存量之和

2 复制对象:将值类型的字段复制到新分配的内存中。

3 返回地址:将已装箱的值类型对象的地址返回给引用类型的变量

拆箱的过程为

1 检查实例:首先检查变量是否为null,如果是则抛出NullRerenceException异常;再检查变量的引用指向的对象是不是给定值类型的已装箱对象,如果不是,则抛出InvalidCastEXception异常。
2 返回地址:返回已装箱实例中属于原值类型的已装箱对象,如果不是,则抛出InvalidCastException异常
到此,拆箱过程已结束,但是伴随着拆箱

注意

  1. 装箱和拆箱都是针对值类型而言的,而引用类型一致都是在托管堆中的,即总是以装箱的形式存在的。

2 .装箱和拆箱并不是互逆的过程,实际上装箱的性能开销远比拆箱的性能开销大,并且伴随着拆箱的字段复制 实际上不属于拆箱
3 .只有值类型装箱之后的引用类型才能被拆箱,而并不是所有的引用类型都能被拆箱,除非装箱实例强制转化为值类型或则转化为非原装箱的值类型,会抛出InvalidCastException异常
4 . 我们拆箱前怎么知道这个引用类型是否是期望的那个值类型的装箱形式。我们有两种方式一种是用is/os 操作符来判断;还有一种方法是object类的gettype方法。