C#装箱和拆箱以及相关IL代码简介示例
发表于2018-09-12
本文要使用的工具有csc.exe(微软。Net Framework已经帮我们装好,路径是:C:\Windows\Microsoft.NET\Framework64\v4.0.30319)程序集生成工具,ildasm.exe(IL代码查看,同上,路径是:C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin)工具;
什么是装箱和拆箱
简单来说:装箱是将值类型转换为引用类型 ;拆箱是将引用类型转换为值类型。(网上广为流传)
C#中值类型和引用类型的最终基类都是Object类型(它本身是一个引用类型)。也就是说,值类型也可以当做引用类型来处理。而这种机制的底层处理就是通过装箱和拆箱的方式来进行,利用装箱和拆箱功能,可通过允许值类型的任何值与Object 类型的值相互转换,将值类型与引用类型链接起来 。
查看下文的代码装箱次数
using System;
class Program
{
static void Main(string[] args)
{
Int32 v = 5;
Object o = v; //第一次装箱
v = 32;
Console.WriteLine(v + ", " + (Int32)o);//第二第三次装箱
}
}
IL代码如下所示(相关描述已经在代码中注释):
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 47 (0x2f)
.maxstack 3
.locals init (int32 V_0,
object V_1)
IL_0000: nop
//将5加载到v中
IL_0001: ldc.i4.5
IL_0002: stloc.0
//对v装箱,将引用指针存储在o中
IL_0003: ldloc.0
IL_0004: box [mscorlib]System.Int32
IL_0009: stloc.1
//将32装载到v中
IL_000a: ldc.i4.s 32
IL_000c: stloc.0
//对v装箱,将指针保留在栈上,为Concat连接操作做准备
IL_000d: ldloc.0
IL_000e: box [mscorlib]System.Int32
//将字符串", "加载到栈上,为Concat连接做准备
IL_0013: ldstr ", "
//对o执行拆箱操作,在栈上创建Int32的内存
IL_0018: ldloc.1
IL_0019: unbox.any [mscorlib]System.Int32
//对Int32装箱,将指针保留在栈上为Concat做准备
IL_001e: box [mscorlib]System.Int32
//调用Concat
IL_0023: call string [mscorlib]System.String::Concat(object,
object,
object)
//将Concat返回的字符串传递给WriteLine
IL_0028: call void [mscorlib]System.Console::WriteLine(string)
IL_002d: nop
//从Main返回,终止程序
IL_002e: ret
} // end of method Program::Main
来自:https://blog.csdn.net/virus2014/article/details/80145412
