A confusion about value types
I'm confused about one point, if i declare an instance of Object class. It will be reserved on the heap, but when i declare, any primitive type instance which derived from System.ValueType which is further derived from Object class, then the part of it used by Object class is also reserved on the stack.
Why is that, or is it the case t开发者_JS百科hat Object class takes no space ?
Your reasoning seems to go like this:
- System.Int32 is derived from System.Object
- a derived type is always laid out in memory in the same way as its base type
- therefore, System.Int32 is laid out in memory the same as System.Object
Yes?
The second premise is false. Derivation and memory layout have pretty much nothing to do with each other. Do you believe this premise to be true? If so, what led you to believe it?
UPDATE: I think it would be helpful to describe how a method call on a value type works.
Suppose you've got a value type:
struct S {
public int x;
public override string ToString() { return "Hello!" + x; }
}
...
S s = new S();
s.x = 0x00112233;
s.ToString();
What code do we generate? The code does this:
- reserve four bytes on the stack for s.x.
- write the bytes 00 11 22 33 into that memory.
- call the method S.ToString, passing a reference to the memory location we just allocated on the stack.
Why do we need to store anything other than the four bytes of s.x on the stack? We have everything we need already in hand to do the call: a reference to the variable containing the instance of S, and the exact name and location of the exact method implementation that we're calling. There is no need to store anything having to do with System.Object anywhere. There is no "part of it used by object class"; we have no need of such a thing, so there isn't any such thing.
.Net Value Types are always allocated on the stack. Right?
Nope, sorry but not always
If you declare a value type as a local variable in a function, then yes, it will be allocated on the stack.
If the value type is a member on an class, then it will be stored on the heap, as part of the object.
As often, see Eric Lippert's blog: the stack is an implementation detail. The essential characteristic of value types is that they are passed by value. System.ValueType indeed inherits from System.Object, but you could say value types are treated in a special way: they are always copied by value.
Anything that derives from ValueType is handled differently by the compiler. It's not allocated as an object on the heap, instead it's allocated inline, i.e. as a local variable on the stack or as a member of another object.
A value type doesn't have any extra data as an object has. An object has a type identifier and a reference to a virtual method table, but a value type doesn't need either of those. So, an Int32 for example only needs the four bytes for the actual data.
精彩评论