装箱和拆箱是值类型和引用类型之间相互转换是要执行的操作。
装箱就是将一个值类型转换成等价的引用类型.
它分别以下几个步骤:
- 在堆上为新生成的对象实例分配内存。该对象实例包含数据,但它没有名称。
- 将
栈
上值类型变量的值复制到堆上的对象
中 - 将堆上创建的对象的地址返回给引用类型变量
拆箱则是将一个已装箱的引用类型转换为值类型
它分为以下两步:
- 获取已装箱的对象的地址。
- 将值从堆上的对象中复制到堆栈上的值变量中。
可见,装箱和拆箱需要反复在堆上进行操作,因此,在程序中应该尽量避免无意义的装
箱和拆箱。
class Box
{
public static void PackingAndUnPacking()
{
// 装箱
int i = 1;
Object boxed = i;
Console.WriteLine("Packing: " + boxed);
// 拆箱
int j = (int)boxed;
Console.WriteLine("UnPacking: " + j);
}
}
装箱操作和拆箱操作是要额外耗费cpu和内存资源的,在c# 2.0之后引入了泛型来减少装箱操作和拆箱操作消耗。
1 使用非泛型集合时引发的装箱和拆箱操作
var array = new ArrayList();
array.Add(1);
array.Add(2);
foreach (int value in array)
{
Console.WriteLine(“value is {0}”,value);
}
没有使用泛型. 会发生两次装箱操作和两次拆箱操作.
当往list中添加数字类型时,会将int类型元素装箱成为Object.
在foreach过程中.Object拆箱为int类型.
var list = new List<int>();
list.Add(1);
list.Add(2);
foreach (int value in list)
{
Console.WriteLine("value is {0}", value);
}
差别在于集合的类型使用了泛型的List,而非ArrayList;
上述代码只会在Console.WriteLine()方法时执行2次装箱操作,不需要拆箱操作。
泛型可以避免装箱拆箱带来的不必要的性能消耗;当然泛型的好处不止于此,泛型还可以增加程序的可读性,使程序更容易被复用等等