首页 > 代码库 > 装箱和拆箱

装箱和拆箱

 

1. 装箱是将值类型转换为 object 类型或由此值类型实现的任何接口类型的过程。装箱是隐式的。

当 CLR 对值类型进行装箱时,会将该值包装到 System.Object 内部,再将后者存储在托管堆上。

装箱和取消装箱的概念是类型系统 C# 统一视图的基础,其中任一类型的值都被视为一个对象。

 

2. 拆箱是从 object 类型到值类型或从接口类型到实现该接口的值类型的显式转换。

拆箱操作包括以下两步:
检查对象实例,以确保它是给定值类型的装箱值。
将该值从实例复制到值类型变量中。

 

相对于简单的赋值而言,装箱和拆箱过程需要进行大量的计算。

 对值类型进行装箱时,必须分配并构造一个新对象。 

拆箱所需的强制转换也需要进行大量的计算,只是程度较轻。

 

3. 下面的语句演示装箱和拆箱两种操作:

int i = 123; // a value type
object obj = i; // boxing
int j = (int)obj; // unboxing

要在运行时成功拆箱值类型,被拆箱的项必须是对一个对象的引用,该对象是先前通过装箱该值类型的实例创建的。 null causes a NullReferenceException.‘ data-guid="28743a40d8c06798f09381ab303bc59a">尝试拆箱 null 会导致 NullReferenceException InvalidCastException.‘ data-guid="d5eae09cead581eb6371f4223ed02145">尝试拆箱对不兼容值类型的引用会导致 InvalidCastException

InvalidCastException.‘ data-guid="d5eae09cead581eb6371f4223ed02145">例如:

class TestUnboxing
{
    static void Main()
    {
        int i = 123;
        object o = i;  // implicit boxing 隐式装箱

        try
        {
            int j = (short)o;  // attempt to unbox 尝试拆箱

            System.Console.WriteLine("Unboxing OK.");
        }
        catch (System.InvalidCastException e)
        {
            System.Console.WriteLine("{0} Error: Incorrect unboxing.", e.Message);
        }
    }
}

此程序输出:
Specified cast is not valid. Error: Incorrect unboxing. 因为o不是short型的装箱值
如果将下列语句:
int j = (short) o;
更改为:
int j = (int) o;
将执行转换,并将得到以下输出:
Unboxing OK.