3

It seems like a big deal is made out of boxing and unboxing. Are there so many uses of the object type that we really have to be super aware of this?

What are very practical instances when boxing/unboxing is needed?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Alex Gordon
  • 57,446
  • 287
  • 670
  • 1,062
  • possible duplicate of [Boxing and unboxing: when does it come up?](http://stackoverflow.com/questions/1949122/boxing-and-unboxing-when-does-it-come-up) – H H Oct 22 '10 at 20:47
  • the responses are good, but can u please come up wiht better practical applications – Alex Gordon Oct 23 '10 at 00:02
  • Boxing is helpful to understand, particularly if you come from a C background. The fact that you can't pass a reference to a value type, but rather have to package a copy of the value to pass around by reference, reflects one of the key design decisions behind the CLR. This is a big part of what is meant when managed code is called 'safe' or 'verifiable'. – Dan Bryant Oct 23 '10 at 01:19

2 Answers2

13

It depends.

I think that it's currently less of an issue than it was previously. If you make sure to use the generic collections within the framework (ie: use List<T> instead of ArrayList), then it will likely not be a major issue for you.

This was a huge issue in .NET 1.1, as most collections worked on object, since there were no generic collections. In .NET 1.1, every time you added an int, for example, into most collections, it got boxed, and every time you pulled it out, it was unboxed. If you were doing this in a tight loop, there could easily be problems. It also caused many errors such as trying to unbox and convert into the inappropriate type, which raises an exception.


The difference is the following:

In .NET 1.1, you would typically use something like an ArrayList:

ArrayList list = new ArrayList();

list.Add(1); // These are all boxing - the integer is getting boxed to add
list.Add(2);   
list.Add(3);

foreach(object item in list)
{
    // Unboxing required here:
    int value = (int)item;
    Console.WriteLine(value);
}

Even worse, since this isn't type safe, you could easily cause serious problems since an unbox and conversion can't happen in a single operation:

foreach(object item in list)
{
    // Trying to unboxing into the wrong type here...
    // This will raise an exception at runtime, but compile fine!
    double value = (double)item;
    Console.WriteLine(value);
}

In .NET 2 and later, however, you could use generic collections:

List<int> list = new List<int>();


list.Add(1); // No boxing now, since it's using generics!
list.Add(2);   
list.Add(3);

foreach(int value in list) // This is now typesafe, and doesn't cause an unboxing operation
{
    Console.WriteLine(value);
}

Boxing and unboxing is still needed today at times. For example, Reflection works entirely on object and not concrete types, so it requires boxing of values in order to use methods like FieldInfo.SetValue.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • @reed im sorry can you elaborate on what is the difference between those two? – Alex Gordon Oct 22 '10 at 20:44
  • 1
    @Reed - good point, generics have helped this issue a lot. There are still some times where you have to be careful, lots of boxing/unboxing in things like for loops can get expensive. – pstrjds Oct 22 '10 at 20:45
  • @i am a girl: I elaborated with an example... – Reed Copsey Oct 22 '10 at 20:48
  • @pstrjds: Yes. It's still worth understanding, but I don't think it's quite as "critical" of an issue as it used to be... – Reed Copsey Oct 22 '10 at 20:48
  • 1
    @Reed I agree it is not as "critical", but its definitely something that should be understood (it is a strongly made point in the .Net framework book for the MCSD exam). Also, excellent examples. Very helpful for someone new to .Net and wanting to learn! – pstrjds Oct 22 '10 at 20:56
  • @Reed - some times we need have a method with signature like this: `public IEnumerable MyMethod() where T : X` i think when we using 'where T : X' we using some sort of boxing implicitly its not just for .net 1.1. – Saeed Amiri Oct 22 '10 at 21:07
  • 2
    @SaeedAlg: Generic constraints (`where T : X`) are actually not related to boxing, nor do they cause boxing. – Reed Copsey Oct 22 '10 at 21:08
2

Boxing/unboxing is needed when you want to treat a value type (information that is passed by copying the value instead of passing a reference, pointer, to it) like a reference type (you just copy a pointer.) To do that, you have to create an object with the value, and then get that value whenever you want to perform an operation on it. It's a lot of overhead compared to just use the value - you have to create an object, and destroy it. And operations to access the value.

As Reed Copsey mentioned, this was a huge issue during .NET 1.0/1.1 since it didn't have generics; when performance was really important you had to create a typed collection. Code generators could very well be a part of your toolkit, both for performance, but also for convenience.

Onkelborg
  • 3,927
  • 1
  • 19
  • 22