装箱(Boxing)是指将值类型转化为Object类型或由此值类型实现任意一接口类型的过程。
- 装箱用于在垃圾回收堆中存储值类型。
- 装箱是值类型到 object 类型或到此值类型所实现的任何接口类型的隐式转换。
- 对值类型装箱会在堆中分配一个对象实例,并将该值复制到新的对象中。
拆箱(UnBoxing)是将从对象中提取值类型。
拆箱是从 object 类型到值类型或从接口类型到实现该接口的值类型的显式转换。 拆箱操作包括:
- 检查对象实例,以确保它是给定值类型的装箱值。
-
将该值从实例复制到值类型变量中。
装箱是隐式的,拆箱是显式的。
性能消耗:
相对于简单的赋值而言,装箱和取消装箱过程需要进行大量的计算。 对值类型进行装箱时,必须分配并构造一个新对象。 次之,取消装箱所需的强制转换也需要进行大量的计算。
附:
C#参考类型:
值类型:
值类型主要由两类组成:
-
结构(Struct)
-
Numeric(数值)类型
-
整型(int)
-
浮点型(float)
-
decimal
-
-
bool
-
用户定义的结构。
-
-
枚举(enum)
引用类型:
引用类型的变量存储对实际数据的引用。
声明引用类型所需的关键字:
- class (类)
- interface (接口)
- delegate (委托)
C#内置引用类型的关键字:
- dynamic
- Object
- String
值类型和引用类型的比较:
- 基于值类型的变量直接包含值。 将一个值类型变量赋给另一个值类型变量时,将复制包含的值。 这与引用类型变量的赋值不同,引用类型变量的赋值只复制对对象的引用,而不复制对象本身。
- 所有的值类型均隐式派生自 System.ValueType。
- 与引用类型不同,不能从值类型派生出新的类型。 但与引用类型相同的是,结构也可以实现接口。
- 与引用类型不同,值类型无法包含 null 值。 但是,可以为 null 的类型 功能允许值类型分配给 null。
- 每种值类型均有一个隐式的默认构造函数来初始化该类型的默认值。
总结:
值类型的变量数据存储数据,而引用类型的变量存储对实际数据的引用。引用类型也称为对象。
C#还有一种类型是指针类型,只用于Unsafe模式,略过不谈。
通过装箱和拆箱操作可以将值类型转换为引用类型,然后再转回值类型,而且除了装箱值类型外,无法将引用类型转换为值类型。
值类型也可以null,这意味着它们能存储其它非值状态。