拆箱与装箱知识分享
一、 拆箱与装箱的定义
拆箱:拆箱是将引用类型转换为值类型
装箱: 值类型将数据项从栈内存自动复制到堆内存的行为
二、什么是值类型?
- 值类型直接将内存存储在栈内,由系统自动释放资源的数据类型。
- 值类型包含:整型(Int)、长整型(long)、浮点型(float)、字符型(char)、布尔型:(bool
)、枚举(enum)、结构:(struct)
- 将一个值类型变量赋给另一个值类型变量时,将复制包含的值。
- 所有的值类型均隐式派生自SystemValueType。
- 所有的值类型都是隐式密封的(sealed),目的是防止其他任何类型从值类型进行派生。
三、什么是引用类型?
- 在c#中所有的类都是引用类型,包括接口。
- 所有的引用类型的实例都分配在托管堆上,c#中new操作符会返回一个内存地址指向当前的对象。
- 内存是托管在堆上的,所以会被gc(垃圾回收机制)收管,所以频繁使用引用类型的话会增加堆的压力。
四、为何需要装箱?
- 为何要将值类型转为引用类型,按理说C#被设计成一种完全面向对象的语言。因此,包括数字、字符、日期、布尔值等等在内的一切,都是对象。似乎只需要一种方式来对待这些对象就可以了。
但是C#不是只停留在学院中和理想中,它必须为性能而妥协,我们知道,对于CPU来说,处理一个完整的对象,需要很多的指令,对于内存来说,又需要很多的内存。如果连整数都是对象,那么性能自然很低。C#于是使用了一种机制,使得这些基本类型在一般的编程中被当作非对象的简单类型处理,在另一些场合,又允许它们被视作是一个对象。这种机制就是装箱和拆箱。
装箱后的对象看上去和一个对象一样,拥有方法,可以当作object处理,拆箱后的变量,看上去又如同C语言中的那些变量、结构体一样,可以直接参与运算和处理。
五、值类型与引用类型在内存中赋值情况
六、内存上的装箱过程如下:
七、 代码分析拆箱与装箱
object b; b = a;//第一次装箱 int c = (int)b; //这是一个拆箱的过程,是将值类型转换为引用类型,再由引用类型转换为值类型的过程 //注:被装过箱的对象才能被拆箱 double d = (double)b; //这个地方程序会引发异常,b在这个地方已经进行一次装箱,对于一个已装过箱对象,显式强制类型转换不能将其转换为其他类型,如需要使用,可以选择convert转换 double s = Convert.ToDouble(b);