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