【问题标题】:How does "boxing" work in .NET?“拳击”如何在 .NET 中工作?
【发布时间】:2011-05-13 20:28:25
【问题描述】:

我知道什么是“拳击”:

object myBox = 5;

现在我想增加我的知识。是否为此装箱操作创建了特殊类型?还是使用了System.Object? .NET 如何处理拳击?

【问题讨论】:

标签: .net


【解决方案1】:

没有特殊类型;装箱值类型是运行时的实现细节。但理解它的最简单方法是想象有一种特殊类型:

class Box<T> where T : struct
{
    T value;
}

Box&lt;T&gt; 类型还实现了 T 的所有方法、接口等,无论 T 碰巧是什么。因此,例如,您可以想象Box&lt;int&gt; 有一个 ToString 方法,该方法简单地在值上调用 int.ToString 并返回结果。

装箱只是一种获取对非引用类型的引用的机制。您只需在事物周围制作一个框并获取对该框的引用。

【讨论】:

    【解决方案2】:

    CLR 处理装箱。

    考虑在这种情况下会发生什么:

    private void myUselessMethod()
    {
         int i = 5;
         object o = i;
    }
    

    'i' 是一个 valueType(一个 Int32),作为一个局部变量,分配在堆栈上,大概只分配 4 个字节。 然后,i 被包装到一个对象中,即装箱。 CLR(公共语言运行时)的作用:

    • 它在托管堆上分配内存:即,为 Int32 提供足够的空间,加上托管堆上的每个对象都必须具有的两个额外开销成员的空间——“类型对象指针”和“同步索引” .
    • 它将值 5 复制到新分配的堆内存中。
    • 它返回堆中内存的地址作为引用o。

    我发现这个装箱/拆箱/引用类型/值类型业务最令人困惑的是,一方面,一切都是对象,甚至值类型也是对象并且派生自System.Object。另一方面,当声明一个 Object 时,它始终是一个引用类型。

    所以

    void myMethod(System.Object o)
    {
        doStuff();
    }
    
    void myCallingMethod()
    {
        int i = 5;
        myMethod(i);
    }
    

    即使i 是一个 int、一个 valueType 和一个对象,因为值类型也是从 System.Object 派生的,但会将它装箱以将其传递给 myMethod。

    【讨论】:

      【解决方案3】:

      正如Bala R 提到的......

      没有比 MSDN 提供的更好的例子了

      Boxing and Unboxing

      【讨论】:

        猜你喜欢
        • 2014-06-19
        • 1970-01-01
        • 2010-09-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多