为什么会这样,或者Object类是否占用空间?
答案 0 :(得分:6)
你的推理似乎是这样的:
是
第二个前提是假的。派生和内存布局几乎没有任何关系。你认为这个前提是真的吗?如果是这样,是什么导致你相信它?
更新:我认为描述一个值类型的方法调用是如何工作的。
假设您有一个值类型:
struct S {
public int x;
public override string ToString() { return "Hello!" + x; }
}
...
S s = new S();
s.x = 0x00112233;
s.ToString();
我们会生成什么代码?代码执行此操作:
为什么我们需要在堆栈上存储除s.x的四个字节以外的任何内容?我们已经拥有了我们需要的所有内容来执行调用:对包含S实例的变量的引用,以及我们正在调用的确切方法实现的确切名称和位置。无需在任何地方存储与System.Object有关的任何内容。没有“对象类使用它的一部分”;我们不需要这样的东西,所以没有这样的东西。
答案 1 :(得分:3)
.Net值类型在堆栈上始终分配。对吗?的
不,对不起但不总是
如果在函数中声明值类型为局部变量,则为yes,它将在堆栈中分配。
如果值类型是类的成员,那么它将作为对象的一部分存储在堆上。
答案 2 :(得分:2)
与往常一样,请参阅Eric Lippert的博客:the stack is an implementation detail。价值类型的本质特征是它们通过价值传递。 System.ValueType确实继承自System.Object,但您可以说以特殊方式处理值类型:它们始终按值复制。
答案 3 :(得分:0)
任何派生自ValueType的内容都由编译器以不同方式处理。它不是作为堆上的对象分配的,而是分配内联,即作为堆栈上的局部变量或作为另一个对象的成员。
值类型没有对象具有的任何额外数据。对象具有类型标识符和对虚方法表的引用,但值类型不需要其中任何一个。因此,Int32例如只需要实际数据的四个字节。