C#装箱与拆箱详解

装箱和拆箱是C#语言中非常重要的两个概念。在C#中,值类型(如int,double,struct等)和引用类型(如class,interface等)是两种完全不同的数据类型。而装箱和拆箱就是这两种类型之间转换的过程。

在C#中,所有的值类型都直接派生自System.ValueType,而System.ValueType又派生自System.Object。这意味着值类型在某种程度上也是对象类型,因此可以访问一些普通对象的方法,如ToStringEqualsGetHashCode等。装箱和拆箱就是C#为了在值类型和引用类型之间建立桥梁而提供的机制。

装箱

当我们将一个值类型转换为object类型或者任何此值类型的接口类型时,就发生了装箱操作。装箱操作涉及到堆内存分配,这是一个相对昂贵的操作。这是因为它需要创建一个新的对象,然后将值类型的值复制到这个新对象。由于装箱操作涉及到内存分配,所以在性能敏感的代码中,我们应尽量避免装箱操作。

int i = 123;  // 创建值类型变量
object o = i; // 装箱操作

拆箱

拆箱是装箱的反向操作,即将一个引用类型转换为值类型。拆箱操作同样也需要进行内存分配。拆箱操作需要类型完全匹配,否则会在运行时抛出InvalidCastException异常。

object o = 123;  // 装箱操作
int i = (int)o;  // 拆箱操作

一个重要的点是,拆箱操作是在已装箱的对象上执行的。如果你试图拆箱一个没有被装箱的对象,你将会得到一个InvalidCastException异常。

性能影响

由于装箱和拆箱都涉及到堆内存操作,所以它们都是有性能开销的。在大量进行装箱和拆箱操作的情况下,这种性能开销可能会变得很明显。因此,在编写代码时,我们应该尽量避免不必要的装箱和拆箱操作。

例如,使用泛型集合(如List)而不是非泛型集合(如ArrayList)可以避免装箱和拆箱操作,因为泛型集合在编译时就已经确定了类型,而非泛型集合在存储值类型时需要进行装箱操作。

总的来说,了解装箱和拆箱以及它们的性能影响,可以帮助我们写出更高效的C#代码。

你可能感兴趣的:(C#学习笔记,c#,C#装箱与拆箱)