从ValueType类的MSDN链接引用
如果值类型必须像对象一样运行,则在堆上分配使值类型看起来像引用对象的包装器,并将值类型的值复制到其中.标记包装器,以便系统知道它包含值类型.
这意味着我的代码就像"integerVariable.ToString();" 创建的包装器对象允许使用此方法,类似于System.Object的所有其他方法.
这种理解是否正确?
这些对象与"常规"对象有何不同?
垃圾收集是否与此类对象不同?如果有,怎么样?
提前致谢.
包装纸是一个"盒子"; 箱子的垃圾收集 - 就垃圾收集器而言没有区别.收集的盒子具有与任何其他对象完全相同的规则和处理.
但是,如果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
(因为它不是(也不能)重写)