.net ValueType包装器的垃圾收集

.net ValueType包装器的垃圾收集,.net,garbage-collection,value-type,.net,Garbage Collection,Value Type,引述 在需要使值类型的行为类似于对象的情况下,会在堆上分配一个使值类型看起来类似于引用对象的包装器,并将值类型的值复制到其中。包装器被标记,以便系统知道它包含值类型 这意味着,当我像“integerVariable.ToString();”这样编写代码时,创建的包装器对象允许使用此方法以及类似的System.object的所有其他方法 这种理解正确吗 这些对象与“常规”对象有何不同 对于这样的对象,垃圾收集是否不同?如果是,如何进行 提前感谢。是的,理解是正确的 这些对象与CLR中的“常规”对象

引述

在需要使值类型的行为类似于对象的情况下,会在堆上分配一个使值类型看起来类似于引用对象的包装器,并将值类型的值复制到其中。包装器被标记,以便系统知道它包含值类型

这意味着,当我像“integerVariable.ToString();”这样编写代码时,创建的包装器对象允许使用此方法以及类似的System.object的所有其他方法

这种理解正确吗

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

对于这样的对象,垃圾收集是否不同?如果是,如何进行


提前感谢。

是的,理解是正确的

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

由于这些对象(也被称为“盒子”,因为它们包装值类型)与任何其他对象一样,垃圾收集器也一样。

包装器是一个“盒子”;重新收集箱子的垃圾-就抓取收集器而言,没有差异。长方体的收集规则和处理方式与任何其他对象完全相同

但是,如果值类型重写了方法(例如
ToString()
),则无需将其框起来以调用该方法。因此,值类型应该(作为惯例)覆盖尽可能多的
对象
方法-p

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

我们有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
中涉及框(因为它不是(不能)重写)

不太正确;如果方法被重写,调用ToString()不会创建一个框,通常是这样。@Marc如果方法没有被重写,为什么要创建一个框?@Munish-因为这是调用object.Blah()方法的唯一方法。如果已知它被结构重写,则可以使用静态调用,这是最正确的方法。
.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 
}