开发者

How does System.Object store "objects" internally?

I was reading about boxing, and the book says that "boxing can be formally defined as the process of explicitly converting a value type into a corresponding reference type by storing the variable in a System.Object." (emphasis added)

My question isn't about boxing, but this got me thinking - how and where does that System.Object instance store the values/variables/objects assigned to it. So I'm wo开发者_Python百科ndering about not only

object objShort = 5;

but also

object someOtherObj = someReallyComplicatedObject;

I've been looking around, including here (MSDN System.Object), and I don't see anywhere that describes how a System.Object instance actually stores its data.

Is the object just simply storing a pointer to the object that was assigned to it, or in the case of boxing, a pointer at the value type on the stack?

(Jon, forgive me if this is in your book too. I have ordered it and it is on the way!)


That description of boxing is inaccurate. The object created isn't just an instance of the bare System.Object; each value type effectively has its own "hidden" corresponding reference type which is just a class deriving from ValueType implementing the same interfaces as the value type, and with a field of the type of the value type. That's certainly how I think of it, at least, and it's roughly how the CLI spec describes it. System.Object itself doesn't have any storage for this.

I'd also want to correct the "storing the variable" part - boxing stores the value in an object. That value might be the value of a variable, or the result of a method call, or whatever.

Of course for reference types, boxing isn't required at all. You really need to distinguish between a reference and an object though - once you've got the two clear in your mind, most other things follow fairly easily. Then remember that the value of a variable is never an object - it's only ever a value type value or a reference (or a pointer :)

(Oh, and this is covered somewhat in C# in Depth, but not in great detail. You might be interested in Eric Lippert's post "The Truth About Value Types" though.)


Imagine that there is a generic reference type that looks like this:

sealed class Box<T> : System.ValueType where T : struct
{
    private T value;
    public Box(T t) 
    {
        this.value = t;
    }
}

Plus a bunch of other dodgy stuff in there:

  • an explicit conversion operator from Box<T> to T.
  • an implicit conversion operator from T to Box<T> which simply calls the constructor.
  • implementations of ToString, GetHashcode and GetType that proxy to this.value.
  • and so on

Conceptually, a boxing conversion from int to object is simply calling the implicit conversion operator from int to Box<int>.

Of course, in reality there is no such type as Box<T> and if there were, it would have to be full of wacky stuff; you're not allowed to override GetType normally, you're not allowed to extend ValueType in a class normally, its behaviour with nullable types is weird, and so on. All those details are implementation details of the CLR, but it helps to imagine that the CLR is just creating an instance of a Very Special Type that does the work of boxing and unboxing.


An object of a reference type in the CLR (including C#) is stored with some metadata that describes what kind of object it is, the state of its lock, and garbage collection information, etc., as well as the actual data that the object stores.

When a value (of a value type) is boxed, then the same sort of structure that is created for a reference type is created for the value type. It is created in the same managed heap that is used for the reference type objects, and it is subject to the same garbage collection. (So it is not a reference to an value on the stack.)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜