10

I was reading Microsoft's Class Room Training Materil. I read the following

Unboxing Unboxing is the opposite of boxing. It is the explicit conversion of a reference type to a value type. Unboxing retrieves a reference to the value type contained within an object. An unboxing operation involves checking the object instance to ensure that the object instance is a boxed value of the given value type. Then, the value from the instance is copied into the value type variable.

**

Unboxing returns a pointer to the data within a boxed object and does not create a copy of the data.

**

I dont really understand the line that i highlighted. it says that when unboxing boxed object, it does not create a copy, it just returns a pointer. If that is true, then a value type variable will be allocated in Heap right?

Ram

RAM
  • 856
  • 1
  • 8
  • 27

2 Answers2

19

In addition to what Guffa said, here is some additional information:

  • The “unboxing” operation described by the text you quoted describes the unbox CIL instruction. The CIL standard has this to say about unbox:

    Unlike box, which is required to make a copy of a value type for use in the object, unbox is not required to copy the value type from the object. Typically it simply computes the address of the value type that is already present inside of the boxed object

  • The unboxing conversions you use in C# are not compiled to unbox. They are compiled to another instruction called unbox.any:

    [...] the unbox.any instruction extracts the value contained within obj (of type O). (It is equivalent to unbox followed by ldobj.)

    In English, this means unbox.any does an unboxing operation (unbox) — which pushes a pointer onto the evaluation stack — followed by the copy operation (ldobj), which converts the pointer to the actual value contained in the value type and pushes that on the evaluation stack instead.

    For completeness, here is the description of ldobj:

    The ldobj instruction copies a value to the evaluation stack. [...] src is an unmanaged pointer (native int), or a managed pointer (&). [...]

    [Rationale: The ldobj instruction can be used to pass a value type as an argument. end rationale]

As far as I am aware, the C# compiler never uses unbox or ldobj, it always uses unbox.any to do unboxing, and ldind.* to dereference references (such as ref/out parameters).

Timwi
  • 65,159
  • 33
  • 165
  • 230
  • 2
    very clear explanation. From the answers given by you and Guffa, I clearly understand Unboxing. Thank you for your great explanation and time - Ram – RAM Sep 19 '10 at 20:45
11

Well, it's true, but not the whole picture.

The unboxing itself only returns a pointer to the data, but you can't use that to access the data in C#. When you have unboxed a value in C#, you always copy it somewhere.

Example:

object o = 42; //box
int i = (int)o; //unbox

The unboxing iself gets the pointer to the value 42 in the object o, then the value is copied into the variable i.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • 1
    Is there anywhere the pointer to unboxed value can be directly used without copying the value? – RAM Sep 18 '10 at 23:03
  • 1
    @RAM: I don't think so, at least not easily. Perhaps you can use `fixed` to pin the object in memory, and get a pointer to the value, but that would be a lot more complicated than just copying the value. Values that get boxed are small, so there is no real reason to try to avoid copying it. – Guffa Sep 18 '10 at 23:37
  • @colinfang: Unboxing a value gets a pointer to the value that is in the object, it doesn't copy the value until you actually use it for something. Unboxing a struct and using a field in it will copy the value of that field out from the boxed struct. – Guffa May 21 '13 at 22:07