什么是装箱、拆箱?
在c#中,装箱和拆箱是两种与值类型和引用类型之间相互转化的操作。
装箱:
1 | int i = 1; |
装箱拆箱会带来额外的开销,所以我们需要尽可能避免。
如何避免?
- 使用泛型
使用List而非ArrayList或Hashtable 因为ArrayList存的是object,需要装箱,而List<T>是泛型集合,编译后其实就是List<int>,内部存的是int[]。1
2
3
4
5ArrayList list = new ArrayList();
list.add(10); // 装箱发生 不推荐
List<int> intL = new List<int>();
intL.add(10); // 无装箱
只要出现值类型 → object / 接口 就会装箱。 - 对于大型结构体,使用in关键字,使其成为只读的
- 对需要频繁装箱的对象,可以先进行缓存
1
2
3
4
5object boxedInt = 10; // 装箱一次
// 避免反复装箱
Method1(boxedInt);
Method2(boxedInt);
Method3(boxedInt); - c重载常用方法
对于自定义结构体,使用ToString()、GetType()等可以避免隐式装箱因为ToString 原本定义在 System.Object 里。1
2
3
4
5
6
7
8struct MyStruct
{
public int i;
public override string ToString()
{
return i.ToString();
}
}
所有值类型最终也都继承自 ValueType -> Object。明确了类型后,可以避免再转化为object。