ValueType包装器的垃圾收集

时间:2009-01-06 10:06:32

标签: .net garbage-collection value-type

MSDN Link for ValueType Class

引用
  

如果值类型的行为必须像对象一样,则在堆上分配使值类型看起来像引用对象的包装器,并将值类型的值复制到其中。标记包装器,以便系统知道它包含值类型。

这意味着我的代码就像“integerVariable.ToString();”创建的包装器对象允许使用此方法,类似于System.Object的所有其他方法。

  

这种理解是否正确?

     

这些对象与“常规”对象有何不同?

     

此类对象的垃圾收集是否不同?如果是,怎么样?

提前致谢。

2 个答案:

答案 0 :(得分:6)

包装是一个“盒子”;垃圾收集盒 - 就垃圾收集器而言,存在 no 差异。收集的盒子具有与任何其他物体完全相同的规则和处理。

但是,如果值类型覆盖方法(例如ToString()),则无需将其设置为调用方法。因此,值类型应该(作为例程)覆盖尽可能多的object方法;-p

您可以看到IL(通过反射器)的差异 - 因此对于C#:

static int GetInteger() {return 123;}
static string TestToString() {
    int i = GetInteger(); // to prove no cheating
    return i.ToString();
}
static Type TestGetType() {
    int i = GetInteger(); // to prove no cheating
    return i.GetType();
}

我们有IL:

.method private hidebysig static string TestToString() cil managed
{
    .maxstack 1
    .locals init (
        [0] int32 i)
    L_0000: call int32 Program::GetInteger()
    L_0005: stloc.0 
    L_0006: ldloca.s i
    L_0008: call instance string [mscorlib]System.Int32::ToString()
    L_000d: ret 
}

.method private hidebysig static class [mscorlib]System.Type TestGetType() cil managed
{
    .maxstack 1
    .locals init (
        [0] int32 i)
    L_0000: call int32 Program::GetInteger()
    L_0005: stloc.0 
    L_0006: ldloc.0 
    L_0007: box int32
    L_000c: call instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
    L_0011: ret 
}

请注意,ToString()不涉及框,但GetType()执行L_0007(因为它不会(不能)覆盖)

答案 1 :(得分:1)

是的,理解是正确的。

这些对象与CLR中的“常规”对象没有区别。

由于这些对象(也称为'box'因为它们包装值类型)就像任何其他对象一样,垃圾收集器也是一样的。