C#中数据类型分为两种:数值类型和引用类型,两种类型相互转换过程中就涉及到装箱与拆箱操作,当数值类型转换为引用类型就称之为装箱,相反过程为拆箱。装箱操作为:
1. 在堆上分配一块内存,用于保存数值类型中的数据。
2. 将数值类型中的数据复制到目的内存中。
3. 引用变量指向该内存位置。
装箱操作是一个隐式操作,拆箱操作为一个显示操作,需要进行类型的强制转换,一个拆箱动作如下:
1. 检查目标数值类型是否合法
2. 复制引用指向的堆数据到数值类型变量中。
测试程序如下:
static void Main(string[] args)
{
int i = 123;
object o = i;
Console.WriteLine("obj:{0}",(int)o);
Console.ReadLine();
}
装箱操作如下:
拆箱操作如下:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// 代码大小 40 (0x28)
.maxstack 2
.locals init ([0] int32 i,
[1] object o)
IL_0000: nop
IL_0001: ldc.i4.s 123
IL_0003: stloc.0
IL_0004: ldloc.0
IL_0005: box [mscorlib]System.Int32 //装箱
IL_000a: stloc.1
IL_000b: ldstr "obj:{0}"
IL_0010: ldloc.1
IL_0011: unbox.any [mscorlib]System.Int32 //拆箱
IL_0016: box [mscorlib]System.Int32 //装箱
IL_001b: call void [mscorlib]System.Console::WriteLine(string,
object)
IL_0020: nop
IL_0021: call string [mscorlib]System.Console::ReadLine()
IL_0026: pop
IL_0027: ret
} // end of method Program::Main
C#中定义的值类型如下:
1. struct定义类型
2. 枚举类型
3. 数值类型(整数、浮点数)
4. 布尔类型
这样也就说明了上面的程序为何有再次装箱操作:整数再次转换为字符串。