4

Possible Duplicate:
What is boxing and unboxing and what are the trade offs?

Ok I understand the basic concept of what happens when you box and unbox.

Box throws the value type (stack object) into a System.Object and stores it on the heap Unbox unpackages that object on the heap holding that value type and throws it back on the stack so it can be used.

Here is what I don't understand:

  1. Why would this need to be done...specific real-world examples

  2. Why is generics so efficient? They say because Generics doesn't need to unbox or box, ok..I don't get why...what's behind that in generics

  3. Why is generics better than lets say other types. Lets say for example other collections?

so all in all I don't understand this in application in the real world in terms of code and then going further how it makes generics better...why it doesn't have to do any of this in the first place when using Generics.

Community
  • 1
  • 1
PositiveGuy
  • 46,620
  • 110
  • 305
  • 471
  • 2
    For many, many good answers to this question search Stack Overflow for 'boxing and unboxing'. – Matthew Vines Oct 25 '10 at 14:32
  • that thread does not answer my question Matt. I said I understand the basic concepts. I'm not seeing any real world explanation that helps me understand the applicability in real code as stated in the 3 points above. I'm not looking for a definition. – PositiveGuy Oct 25 '10 at 14:42
  • Here is a good article from Eric Lippert about value types. A value type isn't necessarily stored on the stack. http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx – Dismissile Oct 25 '10 at 14:43
  • why is this closed. I see no dup thread yet that tells me the applicable examples of all this. – PositiveGuy Oct 25 '10 at 15:38
  • All three of your list points are answered in the [accepted answer](http://stackoverflow.com/questions/13055/what-is-boxing-and-unboxing-and-what-are-the-trade-offs/25324#25324) to what was marked as a duplicate. – jball Oct 25 '10 at 15:44
  • Re: the request for a real-world example - there are so many that are trivially available, e.g. a `List` for data values instead of an `ArrayList` in which each element is an `int` boxed to an `object` that must be unboxed when used. – jball Oct 25 '10 at 15:50
  • again, List is not what I am asking for. Real World is situational, not just syntactical. For example anyone can tell you and give you textbook examples of an Abstract class but it's the HOW you use it in REAL WORLD APPS regardless if there are MANY ways to do it, I just needed a couple examples in real code where people really had to worrry about this..and it's not JUST generics although that was an additional add-on question of mine to relate to the general topic. I need to understand outside int, lists, etc. why I need to worry and where boxing and boxing happens..period. – PositiveGuy Oct 25 '10 at 20:33
  • ArrayList in which each element is an int boxed to an object...OK WHY? why does it even have to be boxed. Did you read my freakin comments? – PositiveGuy Oct 25 '10 at 20:34
  • why does any value type have to be boxed period! And the answer that I'm NOT looking for is "because the ArrayList only can contain System.Object boxing of value types like int". I'm asking why..the underling CLR why Arratlist requires boxing or even not lists, just why would you need to box a value type in OTHER situations. – PositiveGuy Oct 25 '10 at 20:36
  • sorry the last 3 posts were for @jball cause I really can't believe the attitude about stomping out me as a person saying that my question is trivial. It's not trivial. I"m asking for trivial answers on real-world examples that are concrete. – PositiveGuy Oct 25 '10 at 20:45
  • @CoffeeAddict, please read the answers to the other question first, then post a new question if there's something not covered there. And seriously, you can't think of any real-world examples where you need a list of one type of primitives? You're straining credulity there. – jball Oct 25 '10 at 21:53
  • jball you're not READING. You are not COMPREHENDING the question or my comments. – PositiveGuy Oct 25 '10 at 22:53
  • Nobody has answered WHY boxing is needed (yes it stores a value type but WHY does the compiler or whatever it is need it boxed in the first place!)...and where else is boxing done other than LISTS. Read Jballs. – PositiveGuy Oct 25 '10 at 23:00
  • 1
    @CoffeeAddict, yes they have. E.g., [boxed values typically play better with other types in the system. Since they are first-class data structures in the language, they have the expected metadata and structure that other data structures have.](http://stackoverflow.com/questions/13055/what-is-boxing-and-unboxing-and-what-are-the-trade-offs/25324#25324) and – jball Oct 25 '10 at 23:17
  • @CoffeeAddict ...cont. , [For example, in java, you may need to convert an int value into an Integer (boxing) if you want to store it in a Collection because primitives can't be stored in a Collection, only objects.](http://stackoverflow.com/questions/13055/what-is-boxing-and-unboxing-and-what-are-the-trade-offs/13056#13056)... Please read the answers. You might save yourself a bit of undue agitation. – jball Oct 25 '10 at 23:18
  • thanks I gave you a thumbs up for that +1. Now I know what to search for other than System.Object to see what first class types mean. I really want to know the under the hood reasons why it's preferred to store objects in lets say other collections or why other values are boxed automatically for whatever x reasons outside of lists. This is still blurry to me on why box it but now I have something to go on a little. Thanks. – PositiveGuy Oct 26 '10 at 01:12

8 Answers8

5
  1. Boxing needs to be done whenever you want to hold an int in an object variable.
  2. A generic collection of ints contains an int[] instead of an object[].
  3. Putting an int into the object[] behind a non-generic collection requires you to box the int.
    Putting an int into the int[] behind a generic collection does not invlove any boxing.
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 3
    Your first point seems like it kind of answers the question with the content of the question. I think the OP wants to know *why* you would need to hold an `int` in an `object`. +1 for the other points, though. – eldarerathis Oct 25 '10 at 14:31
  • 1) Boxing needs to be done whenever you want to hold an int in an object variable. Ok I've seen this example on MSDN. I don't get WHY you'd need to do such a thing – PositiveGuy Oct 25 '10 at 14:43
  • 2) so you're saying a generic collection doesn't contain a bunch of boxed objects? It holds the actual value-type? – PositiveGuy Oct 25 '10 at 14:43
  • 3) Because other collections hold values as System.Object (boxed)..is that what you're saying? Ok what collections? – PositiveGuy Oct 25 '10 at 14:44
  • To follow @eldarerathis' comment, you could reword your 1. to something like "whenever you have an int and want to use a method/data structure that takes an object" – chiccodoro Oct 25 '10 at 14:45
  • well I don't want to base this just off an int example as that's the defacto example that does me absolutely no good in understanding this...I'm leaving it open to other "real world code" situations. What if I have a collection of custom objects? what If I have something else? – PositiveGuy Oct 25 '10 at 14:59
  • 1
    @CoffeeAddict: Boxing is necessary for all value types (`struct`s and built-in numeric types) – SLaks Oct 25 '10 at 15:04
3

Firstly, the stack and heap are implementation details. a value type isnt defined by being on the stack. there is nothing to say that the concept of stack and heap will be used for all systems able to host the CLR: Link

That aside:

when a value type is boxed, the data in that value type is read, an object is created, and the data is copied to the new object. if you are boxing all the items in a collection, this is a lot of overhead.

if you have a collection of value types and are iterating over them, this will happen for each read, then the items are then unboxed (the reverse of the process) just to read a value!!

Generic collections are strongly typed to the type being stored in them, and therefore no boxing or unboxing needs to occur.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
TimC
  • 1,051
  • 9
  • 16
  • omg that article rocks...thanks! – PositiveGuy Oct 25 '10 at 15:04
  • (when a value type is boxed, the data in that value type is read, an object is created, and the data is copied to the new object. if you are boxing all the items in a collection, this is a lot of overhead.) Ok why does it need to box in the first place!?? – PositiveGuy Oct 25 '10 at 15:05
2

Here is a response around the unboxing/boxing portion.

I'm not sure how it is implemented in mono, but generic interfaces will help because the compiler creates a new function of the specific type for each different type used (internally, there are a few cases where it can utilize the same generated function). If a function of the specific type is generated, there is no need to box/unbox the type.

This is why the Collections.Generic library was a big hit at .NET 2.0 because collections no longer required boxing and became significantly more efficient.

In regards to why are generics better then other collections outside the boxing/unboxing scope is that they also force type. No longer can you readily toss a collection around which can hold any type. It can prevent bugs at compile time, versus seeing them at run time.

Community
  • 1
  • 1
Aaron McIver
  • 24,527
  • 5
  • 59
  • 88
2

MSDN has a nice article: Boxing and Unboxing (C# Programming Guide)

In relation to simple assignments, boxing and unboxing are computationally expensive processes. When a value type is boxed, a new object must be allocated and constructed. To a lesser degree, the cast required for unboxing is also expensive computationally.

Boxing is used to store value types in the garbage-collected heap. Boxing is an implicit conversion of a value type to the type object or to any interface type implemented by this value type. Boxing a value type allocates an object instance on the heap and copies the value into the new object.

Unboxing is an explicit conversion from the type object to a value type or from an interface type to a value type that implements the interface. An unboxing operation consists of:

  • Checking the object instance to make sure that it is a boxed value of the given value type.

  • Copying the value from the instance into the value-type variable.

Check also: Exploring C# Boxing

And read Jeffrey Richter's Type fundamentals. Here Two sample chapters plus full TOC from Jeffrey Richter's "CLR via C#" (Microsoft Press, 2010) he published some time ago.

Also some notes from Jeffrey Richter's book CLR via C#:

It’s possible to convert a value type to a reference type by using a mechanism called boxing.

Internally, here’s what happens when an instance of a value type is boxed:

  1. Memory is allocated from the managed heap. The amount of memory allocated is the size required by the value type’s fields plus the two additional overhead members (the type object pointer and the sync block index) required by all objects on the managed heap.

  2. The value type’s fields are copied to the newly allocated heap memory.

  3. The address of the object is returned. This address is now a reference to an object; the value type is now a reference type. The C# compiler automatically produces the IL code necessary to box a value type instance, but you still need to understand what’s going on internally so that you’re aware of code size and performance issues.


Note. It should be noted that the FCL now includes a new set of generic collection classes that make the non-generic collection classes obsolete. For example, you should use the System.Collections.Generic.List class instead of the System.Collections.ArrayList class. The generic collection classes offer many improvements over the non-generic equivalents. For example, the API has been cleaned up and improved, and the performance of the collection classes has been greatly improved as well. But one of the biggest improvements is that the generic collection classes allow you to work with collections of value types without requiring that items in the collection be boxed/unboxed. This in itself greatly improves performance because far fewer objects will be created on the managed heap thereby reducing the number of garbage collections required by your application. Furthermore, you will get compile-time type safety, and your source code will be cleaner due to fewer casts. This will all be explained in further detail in Chapter 12, “Generics.”


I don't want overquote full chapter here. Read his book and you gain some details on process and receive some answers. And BTW, answer to your question quite a few here on SO, around Web and in many books. It is fundamental knowledge you certainly have to understand.

Nick Martyshchenko
  • 4,231
  • 2
  • 20
  • 24
  • this again does not help me, it's just definition. – PositiveGuy Oct 25 '10 at 14:43
  • 1
    Definitions? Do you check all my links? They includes some measuring and fundamental processes involving in boxing / unboxing. If you don't need definitions, so you don't want to know how it implemeted, what kind of argues you'll accept? – Nick Martyshchenko Oct 25 '10 at 14:50
1

Here is an interesting read from Eric Lippert (The truth about value types): Link

regarding your statement:

Box throws the value type (stack object) into a System.Object and stores it on the heap Unbox unpackages that object on the heap holding that value type and throws it back on the stack so it can be used.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Stephan Schinkel
  • 5,270
  • 1
  • 25
  • 42
0

To put it simple boxing and unboxing takes alot of time. Why - beacuse it's faster to use known type from the start then let this handle for runtime.

  1. In colection of objects can contain differnt items : string, int, double, etc. and you must check every time that your operation with variable is corect.
  2. Convert from one type to enother takes time.
  3. Generic are much faster and encourage you to use them, old collections exist for backward compability
Ash
  • 1,924
  • 1
  • 13
  • 14
  • "Why - beacuse it's faster to use known type from the start then let this handle for runtime." Don't get it. Why and when would it handle what at runtime? – PositiveGuy Oct 25 '10 at 14:45
  • so you're saying other collections are a collection of boxed value-types possibly and they could be different value-types? What about an array...does that have a array of objects or value types? I thought that an array must be all a certain type it's storing such as all ints or strings...in that case no need to box in an array right? – PositiveGuy Oct 25 '10 at 14:46
  • object[] array = new object[] { 'a', 3, 4.0 }; - beacuse object is the highest in the hierarhy and you can pack in it any item – Ash Oct 25 '10 at 14:52
  • Ok, but still so if you create an array of object, then the array is still storing value types? No right? It's storing objects...so 'a', 3, etc. have to be boxed? – PositiveGuy Oct 25 '10 at 15:10
0
  1. This needs to be done because at the IL level there are different instructions for value types than for reference types (ldfld vs ldflda , checkout the dissassembly for a method that calls someValueType.ToString() vs someReferenceType.ToString() and you'll see that the instructions are different).

    These instructions are not compatible so, when you need to pass a value type to a method as an object, that value needs to be wrapped in a reference type (boxing). This is ineficient because the runtime needs to copy the value type and then create a new boxing type in order to pass one value.

  2. Generics are faster because value types can be stored as values and not references so no boxing is needed. Take ArrayList vs List<int>. If you want to put 1 into an ArrayList, the CLR needs to box the int so that it can be stored in a object[]. List<T> however, uses a T[] to store the list contents so List uses a int[] which means that 1 doesn't need to be boxed in order to put it in the array.

Abel
  • 56,041
  • 24
  • 146
  • 247
Wesley Wiser
  • 9,491
  • 4
  • 50
  • 69
  • (when you need to pass a value type to a method as an objec). I don't get it, why would you need to pass a value type to a method as an object? Example and reason? – PositiveGuy Oct 25 '10 at 15:07
  • (Generics are faster because value types can be stored as values and not references so no boxing is needed) Do you mean objects instead of the term "references" in that sentence? I'm confused. I know variables are pointing to the corresponding object on the heap via a reference. – PositiveGuy Oct 25 '10 at 15:08
  • You might need to pass a value type as an object if you are working with legacy (.net 1.1) code which doesn't support generics. This could happen if you are working on a project that targeted .net 1.1 at some point. – Wesley Wiser Oct 25 '10 at 18:19
  • Yes, I meant objects. Sorry for the confusion. – Wesley Wiser Oct 25 '10 at 18:21
  • Why does a value type need to be passed to a method param as an object? I mean isn't the value itself and object? If a method param does not have a ref keyword before it, doesn't it accept value types in that case automatically? – PositiveGuy Oct 25 '10 at 23:08
  • CLR needs to box the int so that it can be stored in a object[]....why does the CLR need this boxed? – PositiveGuy Oct 25 '10 at 23:08
  • Why can't an array list store values? instead of a list of boxed value types in a bunch of System.Object instances that make up the list? – PositiveGuy Oct 25 '10 at 23:09
  • A value is an "object" in the object oriented sense of the word but `object` as a parameter type in .net\c# is a reference type which means that any value types need to be boxed in order to be used as the `object` parameter. – Wesley Wiser Oct 27 '10 at 14:22
  • `ArrayList` can't store value types because it is backed by an `object[]` array which holds references not values therefore values need to be boxed. Generic collections like `List` are backed by a `T[]` so `List` is backed by `int[]` which can hold values. – Wesley Wiser Oct 27 '10 at 14:24
0

Suppose I want to store a bunch of variables of type Long in a List, but the system supported neither value-type generics nor boxing. The way to go about storing such values would be to define a new class "BoxedLong", which held a single field "Value" of type Long. Then to add a value to the list, one would create a new instance of a BoxedLong, set its Value field to the desired value, and store that in the list. To retrieve a value from the list, one would retrieve a BoxedLong object from the list, and take the value from its Value field.

When a value type is passed to something that expects an Object, the above is essentially what happens under the hood, except without the new identifier names.

When using generics with value types, the system doesn't use an value-holder class and pass it to routines which expect to work with objects. Instead, the system creates a new version of the routine that will work with the value type in question. If five different value types are passed to a generic routine, five different versions of the routine will be generated. In general, this will yield more code than would the use of a value-holder class, but the code will have to do less work every time a value is passed in or retrieved. Since most routines will have many values of each type passed in or out, the cost of generating different versions of the routine will be more than recouped by the elimination of boxing/unboxing operations.

supercat
  • 77,689
  • 9
  • 166
  • 211