Allegedly, they are more efficient than their non-generic counterparts
because they avoid boxing.
Not allegedly. They are.
How is it possible to avoid boxing whenever generic code is used?
Wouldn't autoboxing still require whenever open type is expended and
used for value types as in the example below:
List<int> list=new List<int>();
list.Add(5); //Wouldn't this auto-box into Integer?
No. For value types, a whole new instance of the type is created for each
different type used as a type parameter for the class. So, when you use
List<int>, you get a version of List<T> that uses unboxed ints inside.
Using the Add() method as an example, here's a simplified version of
what's going on. The class might look something like this:
class List<T>
{
// Default storage length is 4 elements
private T[] _rgt = new T[4];
private _ctCur;
private _ctMax = 4;
public void Add(T t)
{
if (_ctCur == _ctMax)
{
// reallocate and copy to make room (code not shown here)
}
_rgt[_ctCur++] = t;
}
}
When you use the class as List<int>, a new type is created where "T" is
replaced by "int" everywhere. So the class winds up being like this:
class List<int>
{
// Default storage length is 4 elements
private int[] _rgt = new int[4];
private _ctCur;
private _ctMax = 4;
public void Add(int t)
{
if (_ctCur == _ctMax)
{
// reallocate and copy to make room (code not shown here)
}
_rgt[_ctCur++] = t;
}
}
And you'll note that in the above, there's no need to box the parameter to
the Add() method when it's called. It simply is passed and used as any
other value type might be.
Note that the reified generic type is handled different for value types
and reference types. For a reference type, there's no need to create a
whole new reified version of the generic type for each different reference
type used; the same code can be reused, and internally it just deals with
the references. But in order to avoid boxing of value types, a new type
has to be built for each different value type that is used as a type
parameter for the generic type. If you had a List<int> and a List<double>
in your program, that would result in two completely different reified
types being created from the generic type.
Pete