C# 之装箱与拆箱

本文详细介绍了C#中的装箱和拆箱概念,值类型和引用类型的区别,以及它们在内存中的分配。装箱是值类型到object或接口类型的隐式转换,而拆箱是从object到值类型的显式转换。文章通过示例说明装箱和拆箱的使用,并讨论了在某些场景下如何避免不必要的装箱以提高性能。此外,还探讨了装箱和拆箱对执行效率的影响,以及如何通过提前装箱进行优化。
摘要由CSDN通过智能技术生成
知识点 
  1. 值类型。
    1. 值类型是在栈中分配内存,在声明时初始化才能使用,不能为null。
    2. 值类型超出作用范围系统自动释放内存。
    3. 主要由两类组成:结构,枚举(enum),结构分为以下几类:
      1. 整型(Sbyte、Byte、Char、Short、Ushort、Int、Uint、Long、Ulong)
      2. 浮点型(Float、Double)
      3. decimal
      4. bool
      5. 用户定义的结构(struct)
  2. 引用类型。
    1. 引用类型在堆中分配内存,初始化时默认为null。
    2. 引用类型是通过垃圾回收机制进行回收。
    3. 包括类、接口、委托、数组以及内置引用类型object与string。
概念

由于C#中所有的数据类型都是由基类System.Object继承而来的,所以值类型和引用类型的值可以通过显式(或隐式)操作相互转换,而这转换过程也就是装箱(boxing)和拆箱(unboxing)过程。

  1. 装箱 是值类型到 object 类型或到此值类型所实现的任何接口类型的隐式转换(就算实现了某个接口,转为接口依旧要装箱)。对值类型装箱会在堆中分配一个对象实例,并将该值复制到新的对象中。 
  2. 拆箱(取消装箱)是从 object 类型到值类型或从接口类型到实现该接口的值类型的显式转换。取消装箱操作包括:
    1. 检查对象实例,确保它是给定值类型的一个装箱值。(拆箱后没有转成原类型,编译时不会出错,但运行会出错,所以一定要确保这一点。用GetType().ToString()判断时一定要使用类型全称,如:System.String 而不要用String。)

    2. 将该值从实例复制到值类型变量中。

示例

首先写个简单的控制台程序:

// Tutorial_boxing_unboxing.cs
// 装箱与拆箱
using System;

class App
{
    static void Main()
    {
        int i = 32;
        object o = i; //隐式装箱

         Console.WriteLine("o = {0}", o);

        Console.Read();
    }
}

 其中object o = i这里我们进行了装箱操作,然后我们用MSIL 反汇编程序查看下生成的.exe程序的内部机理。

 1 .method private hidebysig static void  Main() cil managed
 2 {
 3   .entrypoint
 4   // 代码大小       30 (0x1e)
 5   .maxstack  2
 6   .locals init ([0] int32 i,
 7            [1] object o)
 8   IL_0000:  nop
 9   IL_0001:  ldc.i4.s   32
10   IL_0003:  stloc.0
11   IL_0004:  ldloc.0
12   IL_0005:  box        [mscorlib]System.Int32
13   IL_000a:  stloc.1
14   IL_000b:  ldstr      "o = {0}"
15   IL_0010:  ldloc.1
16   IL_0011:  call       void [mscorlib]System.Console::WriteLine(string,
17                                                                 object)
18   IL_0016:  nop
19   IL_0017:  call       int32 [mscorlib]System.Console::Read()
20   IL_001c:  pop
21   IL_001d:  ret
22 } // end of method App::Main

 其中第12行是我们的装箱操作。(关于IL中出现的操作符代表的操作请查阅MSDN Library中的.NET开发/.NET Framework SDK/类库参考/System.Reflection.Emit/OpCodes 类/OpCodes 字段)

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值