C#装箱和拆箱以及相关IL代码简介示例

发表于2018-09-12
评论0 4k浏览
本文要使用的工具有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

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引