C#装箱与拆箱

含义

  • 装箱:就是把值类型转换为object类型或由此值类型实现的任何接口类型
  • 拆箱:把装箱后的引用类型转换为值类型

装箱与拆箱就是值类型与引用类型的转换,是值类型和引用类型之间的桥梁。只有值类型才存在装箱和拆箱,装箱是隐式的,而拆箱是显示的。装箱与拆箱的过程包含了对堆上内存的操作,故会消耗性能,装箱需要比原数据更多的空间,因为它需要生成引用类型的标准配置:类型对象指针和同步块索引

过程

装箱

int i = 1;
object o = i;
具体过程
  1. 在堆内申请内存,内存大小为值类型的大小,再加上额外固定空间(类型对象指针和同步块索引)
  2. 将值类型的字段拷贝到新分配的内存中
  3. 返回新引用对象的内存地址(给栈上的引用)
    C#装箱与拆箱_第1张图片
    装箱就是生成图中除了i = 1变量之外另外两块内存空间数据的过程

拆箱

拆箱就是把装箱后的引用类型转换为值类型的过程,但是拆箱不是一定成功的,所以存在出现异常的可能

具体过程
int b = (int)o;
  1. 检查是否为Null,否则抛出NullReferenceException异常,检查实例是否为给定值类型的装箱值,否则抛出InvalidCastException异常,最后获得对象各个成员的地址
  2. 创建一个新的int值类型对象b,并将第一步获得的值复制到b中

如何避免装箱与拆箱

C# 2通过引入泛型来解决了装箱与拆箱的问题,我们可以通过使用泛型集合来避免不必要的装箱和拆箱,例子如下:
很多地方会出现隐蔽的装箱操作,例如,当我们需要实现自定义的结构体判等时有如下代码

struct Rectangle
{
   
	public override bool Equals(object obj)
	{
   		
		...
	}
}

我们发现,默认的签名为将两个比较对象转化为object,这便会引起装箱操作,解决办法是实现一个泛型IEquatable接口:

struct

你可能感兴趣的:(C#,C#,拆箱装箱)