引用 ValueType类的MSDN链接

  

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

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

  

这种理解是否正确?

     

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

     

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

提前致谢。

有帮助吗?

解决方案

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

但是,如果value-type重写方法(例如 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 处执行(因为它不是(不能被覆盖)

其他提示

是的,理解是正确的。

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top