Why do we need boxing and unboxing in C#?
.net, boxing, c#
Solution
Why
To have a unified type system and allow value types to have a completely different representation of their underlying data from the way that reference types represent their underlying data (e.g., an `int` is just a bucket of thirty-two bits which is completely different than a reference type).
Think of it like this. You have a variable `o` of type `object`. And now you have an `int` and you want to put it into `o`. `o` is a reference to something somewhere, and the `int` is emphatically not a reference to something somewhere (after all, it's just a number). So, what you do is this: you make a new `object` that can store the `int` and then you assign a reference to that object to `o`. We call this process "boxing."
So, if you don't care about having a unified type system (i.e., reference types and value types have very different representations and you don't want a common way to "represent" the two) then you don't need boxing. If you don't care about having `int` represent their underlying value (i.e., instead have `int` be reference types too and just store a reference to their underlying value) then you don't need boxing.
where should I use it.
For example, the old collection type `ArrayList` only eats `object`s. That is, it only stores references to somethings that live somewhere. Without boxing you cannot put an `int` into such a collection. But with boxing, you can.
Now, in the days of generics you don't really need this and can generally go merrily along without thinking about the issue. But there are a few caveats to be aware of:
This is correct:
double e = 2.718281828459045;
int ee = (int)e;
This is not:
double e = 2.718281828459045;
object o = e; // box
int ee = (int)o; // runtime exception
Instead you must do this:
double e = 2.718281828459045;
object o = e; // box
int ee = (int)(double)o;
First we have to explicitly unbox the `double` (`(double)o`) and then cast that to an `int`.
What is the result of the following:
double e = 2.718281828459045;
double d = e;
object o1 = d;
object o2 = e;
Console.WriteLine(d == e);
Console.WriteLine(o1 == o2);
Think about it for a second before going on to the next sentence.
If you said `True` and `False` great! Wait, what? That's because `==` on reference types uses reference-equality which checks if the references are equal, not if the underlying values are equal. This is a dangerously easy mistake to make. Perhaps even more subtle
double e = 2.718281828459045;
object o1 = e;
object o2 = e;
Console.WriteLine(o1 == o2);
will also print `False`!
Better to say:
Console.WriteLine(o1.Equals(o2));
which will then, thankfully, print `True`.
One last subtlety:
[struct|class] Point {
public int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
Point p = new Point(1, 1);
object o = p;
p.x = 2;
Console.WriteLine(((Point)o).x);
What is the output? It depends! If `Point` is a `struct` then the output is `1` but if `Point` is a `class` then the output is `2`! A boxing conversion makes a copy of the value being boxed explaining the difference in behavior.
Problem
Why do we need boxing and unboxing in C#? I know what boxing and unboxing is, but I can't comprehend the real use of it. Why and where should I use it? ``` short s = 25; object objshort = s; //Boxing short anothershort = (short)objshort; //Unboxing ```