none
C# 中 装箱与拆箱怎么理解 RRS feed

  • 问题

  • 各位前辈,请问一下,C#中的 装箱 和 拆箱该怎么理解? 我就是有点想不转? 却又说不出来

    2011年10月16日 9:15

答案

  • dear

    装箱就是把实值型别(int)转型成object

    拆箱则是把object转成int

    http://www.dotblogs.com.tw/yc421206/archive/2011/06/08/27311.aspx


    秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/
    2011年10月16日 14:41
  • Hi micheal,
    以下这篇MSDN文档着重介绍了如何装箱与拆箱:
    http://msdn.microsoft.com/zh-cn/library/yz2be5wk.aspx.
    下面我想通过一个例子来展示以下特定情况下对值类型装箱与拆箱:
    假定要创建一个ArrayList对象来容纳一组Point结构, 那么代码可能像下面这样:
    //声明一个值类型
    struct Point {
          public Int32 x, y;
    }
    
    public s ealed class Program {
          public static void Main() { public static void Main() {
                ArrayList a = new ArrayList(); ArrayList a = new ArrayList();
                Point p; Point p; // 分配一个 Point( 不在堆中分配 )
                for (Int32 i = 0; < 10; i++) { for (Int32 i = 0; < 10; i++) {
                      p.x = y i; p.x = y i;   // 初始化值类型中的成员
                      a.Add(p);                 // 对值类型进行装箱,并将引用添加到 对值类型进行装箱,并将引用添加到Arraylist 中
            }
    ...
          }
    }
    

         每一次循环迭代都会初始化一个Point的值类型字段(x和y). 然后, 这个Point会存储到ArrayList中. 但让我们思考一下, ArrayList中究竟存储的是什么? Point结构, Point结构的地址, 还是其他完全不同的东西? 要知道答案我们先来研究一下ArrayList.Add方法:
    public virtual Int32 Add(Object value);
         可以看出, Add需要获取一个Object参数, 换言之Add需要获得对托管堆上一个对象的引用(或指针)来作为参数. 但在这之前的代码中, 传递的是p, 也就是一个Point, 是一个值类型. 为了使代码正确工作, Point值类型必须转换成一个真正的, 在托管堆中的对象, 而且必须获取对这个对象的一个引用. 这时候在调用Add方法之后实际上是对Point值类型进行了装箱.

    其实这一段引自《CLR via C#第三版》, 想要了解更多可以读读这本书, 英文原版和中文版都可以下载到.

    祝你快乐每一天,

    Leo Liu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年10月18日 5:23
    版主

全部回复

  • dear

    装箱就是把实值型别(int)转型成object

    拆箱则是把object转成int

    http://www.dotblogs.com.tw/yc421206/archive/2011/06/08/27311.aspx


    秘訣無它,唯勤而已 http://www.dotblogs.com.tw/yc421206/
    2011年10月16日 14:41
  • Hi micheal,
    以下这篇MSDN文档着重介绍了如何装箱与拆箱:
    http://msdn.microsoft.com/zh-cn/library/yz2be5wk.aspx.
    下面我想通过一个例子来展示以下特定情况下对值类型装箱与拆箱:
    假定要创建一个ArrayList对象来容纳一组Point结构, 那么代码可能像下面这样:
    //声明一个值类型
    struct Point {
          public Int32 x, y;
    }
    
    public s ealed class Program {
          public static void Main() { public static void Main() {
                ArrayList a = new ArrayList(); ArrayList a = new ArrayList();
                Point p; Point p; // 分配一个 Point( 不在堆中分配 )
                for (Int32 i = 0; < 10; i++) { for (Int32 i = 0; < 10; i++) {
                      p.x = y i; p.x = y i;   // 初始化值类型中的成员
                      a.Add(p);                 // 对值类型进行装箱,并将引用添加到 对值类型进行装箱,并将引用添加到Arraylist 中
            }
    ...
          }
    }
    

         每一次循环迭代都会初始化一个Point的值类型字段(x和y). 然后, 这个Point会存储到ArrayList中. 但让我们思考一下, ArrayList中究竟存储的是什么? Point结构, Point结构的地址, 还是其他完全不同的东西? 要知道答案我们先来研究一下ArrayList.Add方法:
    public virtual Int32 Add(Object value);
         可以看出, Add需要获取一个Object参数, 换言之Add需要获得对托管堆上一个对象的引用(或指针)来作为参数. 但在这之前的代码中, 传递的是p, 也就是一个Point, 是一个值类型. 为了使代码正确工作, Point值类型必须转换成一个真正的, 在托管堆中的对象, 而且必须获取对这个对象的一个引用. 这时候在调用Add方法之后实际上是对Point值类型进行了装箱.

    其实这一段引自《CLR via C#第三版》, 想要了解更多可以读读这本书, 英文原版和中文版都可以下载到.

    祝你快乐每一天,

    Leo Liu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年10月18日 5:23
    版主