2.3 C#装箱和拆箱

1.值类型和引用类型

2.装箱

3.拆箱

4.性能影响

5.避免装箱和拆箱


1.值类型和引用类型

csharp 复制代码
值类型:直接存储其值。

例如:int, float, double, char, bool, struct(结构体), enum(枚举)。

它们通常存储在栈 上(注意:如果值类型是类的一个成员,它会随着类的实例存储在堆上)。

引用类型:存储的是其值的内存地址。

例如:string, class(类), object, array(数组), interface。

它们存储在堆 上。

object 类型是所有类型的终极基类,它是一个引用类型。

2.装箱

csharp 复制代码
装箱 是将一个值类型 的值隐式地转换并封装成一个 object 引用类型(或任何该值类型实现的接口类型)的过程。

过程分解:

在堆 上分配一块内存,用于存放值类型的数据以及一些额外的信息(如类型对象指针、同步块索引)。

将栈 上的值类型数据的值 复制到刚刚在堆 上分配好的对象中。

返回这个新分配的堆 上对象的地址(即引用)。
csharp 复制代码
内存示意图
csharp 复制代码
关键点:

装箱是隐式发生的,你不需要写任何特殊的转换代码。

它涉及内存分配和数据复制,所以是有性能开销的

3.拆箱

csharp 复制代码
拆箱 是装箱的逆过程。它是将一个 object 引用类型(或接口类型)中存储的值,显式地转换回原始的值类型。

过程分解:

首先检查 object 引用是否为空(null)。

然后检查这个 object 引用的实际类型是否与你要拆箱成的目标值类型匹配。如果类型不匹配,会抛出 InvalidCastException 异常。

如果类型匹配,就将存储在堆 上那个对象中的值 复制到栈 上的值类型变量中
csharp 复制代码
内存示意图:
csharp 复制代码
关键点:

拆箱是显式的,你必须使用强制类型转换 (目标类型)。

类型必须完全匹配,否则会报错。

例如,你不能把一个装箱的 int 拆箱成 double

4.性能影响

csharp 复制代码
装箱和拆箱虽然方便,但它们是有成本的:

内存分配:每次装箱都需要在堆上新建一个对象。

数据复制:装箱和拆箱都涉及一次数据复制。

垃圾回收压力:堆上新建的对象最终需要由 GC(垃圾回收器)来清理。

在少量操作中,这种开销可以忽略不计。但在循环、大量数据操作(如处理大型集合)时,频繁的装箱拆箱会显著影响程序性能

5.避免装箱和拆箱

csharp 复制代码
相关推荐
夏幻灵4 小时前
JavaScript this 面试:五种绑定规则、优先级与常见面试陷阱
开发语言·javascript·面试
程序猿编码4 小时前
榨干 RTX5090 算力!Qwen3 专用单卡推理引擎,手写C++/CUDA 算子实现 MTP 推测解码
开发语言·c++·大模型推理·qwen3·多模态推理
曹牧5 小时前
C#:未被引用的函数
c#
bkspiderx6 小时前
Qt 插件机制:动态扩展应用功能的核心框架
开发语言·qt·元数据·qt 插件·qpluginloader
程序员老陆6 小时前
深入理解 C++ thread_local:线程私有存储的正确打开方式
开发语言·c++·程序设计
沐晓时光6 小时前
C语言入门,深入理解指针(3)
c语言·开发语言
码云数智-园园6 小时前
unique_ptr 还是 shared_ptr?C++ 智能指针选型与内存泄漏实战分析
java·开发语言
禾小西7 小时前
07丨Redis 哨兵机制:主库故障后,如何恢复服务?
java·开发语言·redis
我不是阵雨7 小时前
JDK 21虚拟线程Pinning陷阱:一文拔钉解困
java·开发语言
徐小黑ACG8 小时前
Golang 基础05 结构体struct
开发语言·算法·golang