Boxing vs Unboxing
Asked Answered
S

6

28

Another recent C# interview question I had was if I knew what Boxing and Unboxing is. I explained that value types are on Stack and reference types on Heap. When a value is cast to a reference type, we call it boxing and vice versa.

Then he asked me to calculate this:

int i = 20;
object j = i;
j = 50;

What is i?

I messed it up and said 50, where its actually 20. Now I think understand it why, however when I was playing with different combinations I was surprised to see this:

Object a = 1; // Boxing
Object b = a; // referencing the pointer on stack to both objects on heap
a = 2; // Boxing

I was expecting to see b == 2 as well, but it isn't, why? Is it because the second boxing destroys and replaces the whole a object on the heap?

Because if I do this, it's fine:

public class TT
{
    public int x;
}

TT t = new TT();
t.x = 1;
TT t2 = new TT();
t2.x = 2;
t = t2;
t.x = 3;

What is t2.x? It should be 3, and it is. But this is not an example of boxing / unboxing at all, is this correct? So how would you summarize this?

Could the values ever become the same in a boxing/unboxing conversion as above?

Sethsethi answered 18/4, 2009 at 21:10 Comment(1)
Also see #13555 for a general readingCritchfield
S
5
  1. You're right the second assignment replaces the first. It doesn't change the boxed value.

  2. Your example doesn't make use of boxing. The value (int) is stored as an int and not boxed.

  3. No, boxing still keeps the immutability guarantee.

Sapienza answered 18/4, 2009 at 21:12 Comment(4)
Hi, Thank you for your answer. may you please elaborate a bit more on "boxing still keeps the immutability guarantee."? Thanks kaveSethsethi
Most value types are immutable, for example: An int can only have one value. If you change the value you're essentially creating a new int. .NET keeps this immutability for boxed objects: If you assign it a new value, you're creating a new boxed int. The same applies to boxed structures.Sapienza
Makes perfectly sense. ThanksSethsethi
@grover: What immutability guarantee? Any boxed value type can easily be mutated freely by trusted and verifiable code written in C++/CLI. Value types like List<T>.Enumerator which implement mutating interfaces, when boxed, will behave as mutable class types.Internist
F
8

Very short: boxing means creating a new instance of a reference type. If you know this, you understand that one instance does not change by creating another.

What you are doing with a = 2 is not changing the value in the 'box', you are creating a new instance of a reference type. So why should anything else change?

Flinch answered 18/4, 2009 at 22:55 Comment(3)
nice explanation, now what happens when you unbox? does the new instance of reference type get destroyed?Treatment
Reference types are always destroyed by garbage collection. So it will be destroyed when not referenced anymore.Flinch
short n sweet answer, really niceUnbodied
S
5
  1. You're right the second assignment replaces the first. It doesn't change the boxed value.

  2. Your example doesn't make use of boxing. The value (int) is stored as an int and not boxed.

  3. No, boxing still keeps the immutability guarantee.

Sapienza answered 18/4, 2009 at 21:12 Comment(4)
Hi, Thank you for your answer. may you please elaborate a bit more on "boxing still keeps the immutability guarantee."? Thanks kaveSethsethi
Most value types are immutable, for example: An int can only have one value. If you change the value you're essentially creating a new int. .NET keeps this immutability for boxed objects: If you assign it a new value, you're creating a new boxed int. The same applies to boxed structures.Sapienza
Makes perfectly sense. ThanksSethsethi
@grover: What immutability guarantee? Any boxed value type can easily be mutated freely by trusted and verifiable code written in C++/CLI. Value types like List<T>.Enumerator which implement mutating interfaces, when boxed, will behave as mutable class types.Internist
I
2

I was expecting to see b == 2 as well, but it isn't, why? is it because the second boxing destroys and replaces the whole (a)-object on heap?

No, not exactly. It leaves the object as it is on the heap (as the b variable is also referencing it) and creates a new object for the new value, which the a variable will reference.

You are right that your second example does not use boxing. You can't access a value that is boxed in any other way than unboxing it, so there is no way to change a boxed value.

Not even a mutable struct like Point can be changed when boxed. To access the properties of the struct you have to unbox it, so you can't change the boxed struct in place.

Inhospitable answered 18/4, 2009 at 21:34 Comment(0)
X
2

Here's another interesting variation that supports Stefan's comments:

        int i = 2;
        object a = i; // Boxing
        object b = a; // Referencing same address on heap as 'a', b == a

        b = i; // New boxing on heap with reference new address, b != a
Xymenes answered 12/7, 2012 at 18:24 Comment(0)
E
1

b is still 1 because b is a reference that still points to the object on the heap with a value of 1. a is 2 because you assigned it to a new object on the heap with a value of 2.

t2.x is 3 because t and t2 are two different references to the same object on the heap.

Ehudd answered 18/4, 2009 at 21:38 Comment(0)
M
0

I think the answer to your question with unboxing is that: The result of an unboxing conversion is a temporary variable (more details: link).

I think you were trying to do sth like:

object a = new Point(10,10);
object b = new Point(20,20);
a = b;

((Point) b).X = 30; //after this operation also a.X should be 30

The above code won't compile - details in the link above, and I think this is the answer to your question:

I was expecting to see b == 2 as well, but it isn't, why? is it because the second boxing destroys and replaces the whole (a)-object on heap?

Meadows answered 18/4, 2009 at 22:27 Comment(1)
It's worth noting that in C++/CLI, there is no difficulty modifying boxed heap objects directly within trusted and verifiable code.Internist

© 2022 - 2024 — McMap. All rights reserved.