C#初级面试题5、拆箱和装箱
在 C# 中,装箱(Boxing) 和 拆箱(Unboxing) 是值类型和引用类型之间相互转换的过程。这是 .NET 类型系统中一个重要的概念。
📦 装箱(Boxing)
装箱 是指将 值类型(比如 int、bool、struct 等)转换为 引用类型(通常是 object 或实现了的接口类型)的过程。
- 装箱是隐式的(自动发生的)。
- 会把值类型的值 复制 到堆上,并返回一个指向该堆对象的引用。
示例:
int i = 123;
object obj = i; // 装箱:int → object
此时,i 的值被复制到堆上,obj 指向这个新创建的对象。
📤 拆箱(Unboxing)
拆箱 是指将 引用类型(之前由值类型装箱而来)显式转换回原来的值类型。
- 拆箱是显式的(需要强制类型转换)。
- 如果类型不匹配,会抛出
InvalidCastException异常。
示例:
object obj = 123; // 装箱
int j = (int)obj; // 拆箱:object → int
⚠️ 注意事项
- 性能开销:装箱/拆箱涉及内存分配(堆)和复制操作,频繁使用会影响性能。
- 类型必须匹配:拆箱时目标类型必须和原始值类型完全一致。
正确做法是先拆箱成object obj = 123; long l = (long)obj; // ❌ 错误!会抛出 InvalidCastExceptionint,再转换:long l = (long)(int)obj; // ✅ 先拆箱,再数值转换
💡 小结
| 操作 | 含义 | 是否隐式 | 示例 |
|---|---|---|---|
| 装箱 | 值类型 → 引用类型(如 object) | 是 | object o = 42; |
| 拆箱 | 引用类型 → 原始值类型 | 否(需强转) | int x = (int)o; |
在泛型(如
List<int>)普及后,装箱/拆箱的使用大大减少,因为泛型避免了不必要的类型转换。
提问
使用装箱和拆箱的代价是什么?
主要是性能,在装箱是必须创建一个新对象,这涉及为其分配内存。
拆箱涉及类型转换。
将字符串赋值给object类型的变量是装箱吗?
不是,因为string不是值类型。
