垃圾收集值类型包装垃圾、类型

2023-09-05 02:57:03 作者:爱像陣風吹过

从 MSDN链接的值类型类报价

在情况下,有必要表现得值类型像一个对象,包装,使值类型看起来像一个参考对象被分配在堆中,值类型的值复制到它。该包装被标记,以便系统知道它包含值类型。

In cases where it is necessary for a value type to behave like an object, a wrapper that makes the value type look like a reference object is allocated on the heap, and the value type's value is copied into it. The wrapper is marked so the system knows that it contains a value type.

这意味着,当我code,如integerVariable.ToString();创建一个包装对象允许使用这种方法和System.Object中的所有类似的其他方法。

This means when I code like "integerVariable.ToString();" a wrapper-object created allows using this method and similarly all the other methods of System.Object.

这是理解是否正确?

如何为这些对象从常规的对象有什么不同?

How are these objects different from the 'regular' objects?

时的垃圾收集这样的对象有什么不同?如果是的话,怎么办?

Is the Garbage Collection different for such object? If yes, how?

在此先感谢。

推荐答案

该包装是一个盒子;重箱垃圾收集 - 有否差别至于grabage收藏家而言。一箱收集完全相同的规则和处理任何其他对象。

The wrapper is a "box"; re garbage collection of boxes - there is no difference as far as the grabage collector is concerned. A box is collected with exactly the same rules and treatment as any other object.

然而,如果一个值类型覆盖的方法(如的ToString()),这是没有必要框它来调用方法。因此,值类型应(作为常规问题)覆盖尽可能多的对象方法尽可能;-p

however, if a value-type overrides a method (such as ToString()), it is not necessary to box it to call the method. Hence, value-types should (as a matter of routine) override as many of the object methods as possible ;-p

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

You can see the difference in the IL (via reflector) - so for the 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 (因为它不(不能)覆盖)

Note that ToString() doesn't involve a box, but GetType() does at L_0007 (since it isn't (can't be) overridden)