Value type objects have two representations: an unboxed form and a boxed form. Reference types are always in a boxed form.
Boxing
Let's say that you wanted to create an ArrayList object to hold a set of Points. With each iteration of the loop, a Point value type is initialized and is stored in the ArrayList. The Add method is prototyped in the following manner:
public virtual void Add(Object value)
The previous code plainly shows that Add takes an Object which is a reference type as a parameter. But here we are passing a Point value type. For this code to work, the Point value type must be converted into a true heap-managed object, and a reference to this object must be obtained. Converting a value type to a reference type is called boxing.
Internally, here's what happens when a value type is boxed:
- When the Add method is called, memory is allocated in the heap for a Point object. The amount of memory allocated is the size required by the value type plus any additional overhead to consider this value a true object. The additional overhead includes a pointer to a virtual method table and a pointer to a sync block.
- The members currently residing in the Point value type (p) are copied into the newly allocated Point object.
- The address of the Point object (a reference type) is returned and is then passed to the Add method.
- The Point object will remain in the heap until it is garbage-collected. The Point value type variable (p) can be reused or freed since the ArrayList never knows anything about it.
Unboxing
Unboxing retrieves a reference to the value type (data fields) contained within an object.
Internally, the following is what happens when a reference type is unboxed:
- The CLR first ensures that the reference type variable is not null and that it refers to an object that is a boxed value of the desired value type. If either test fails, then an InvalidCastException exception is generated.
- If the types do match, then a pointer to the value type contained inside the object is returned.
- The value type that this pointer refers to does not include the usual overhead associated with a true object: a pointer to a virtual method table and a sync block.
No comments:
Post a Comment