Suppose I want to store a bunch of variables of type Long in a list, but the system did not support either generics of type values or boxing. A way to store these values would be to define a new BoxedLong class that contained one Long Value field. Then, to add a value to the list, you can create a new BoxedLong instance, set its Value field to the desired value and save it in the list. To get the value from the list, one could get the BoxedLong object from the list and take the value from its Value field.
When a value type is passed to an object waiting for an object, this essentially happens under the hood, with the exception of no new identifier names.
When using generics with value types, the system does not use a value holder class and passes it to routines that expect to work with objects. Instead, the system creates a new version of the routine that will work with the value of the type in question. If five different types of values are passed to the general routine, five different versions of this procedure will be created. In general, this will give more code than using the class of the owner of the value, but the code will have to do less work each time the value is transferred or retrieved. Since most routines will have many values of each type, transmitted or exited, the cost of generating different versions of the routine will more than pay off by eliminating boxing / unpacking operations.
source share