装箱:将值类型转换为引用类型时发生。值类型是放在栈上的,而引用类型是放在堆上的,将值类型转换为引用类型,堆需要申请内存保存从栈复制过来的数据,这就是一次装箱的过程。
拆箱:将引用类型转换为值类型时发生。与装箱的过程相反,拆箱是将存储在堆上的引用类型值转换为值类型并给值类型。
值类型:常见的值类型有int、float、long、char、bool、enum、struct
引用类型:常见的引用类型有数组、类、接口、委托、object、字符串
问题:装箱和拆箱操作是额外耗费CPU和内存资源的
优化装箱和拆箱
1.避免隐式类型转换
string s="引用类型";
int num=2;
s=s+num;
执行最后一行的代码时,s是引用类型,num是值类型,int类型的变量可以隐式转换为字符串类型的变量,这里就发生了一次装箱的操作
string s="引用类型";
int num=2;
s=s+num.ToString();
将值类型显式转换为引用类型,就不会再发生装箱操作了
2.使用泛型
var arr=new ArrayList();
arr.Add(1);
arr.Add(2);
foreach(int value in arr)
{
Console.WriteLine(value);
}
这执行上面的代码的过程中,添加两只类型的元素发生两次装箱操作,使用foreach遍历时将object类型转成int类型,发生两次拆箱操作,最后执行输出函数的时候,执行两次装箱操作。如果集合中元素更多时,装箱拆箱的操作会更多。
var arr=new List<int>();
arr.Add(1);
arr.Add(2);
foreach(int value in arr)
{
Console.WriteLine(value);
}
与上面代码唯一不同的时就是使用了泛型集合,指定元素的类型,在添加或比遍历取值的时候减少了装箱和拆箱的操作,避免了对性能的浪费
小结:
装箱和拆箱的存在,让值类型与引用类型的转换变得很方便,但是频繁的装箱和拆箱操作会大大降低CPU的性能,因此我们在开发的过程中要合理的使用类型转换和泛型类或方法避免装箱和拆箱操作