Boxe e unboxing com genéricos

A maneira do .NET 1.0 de criar uma coleção de números inteiros (por exemplo) era:

ArrayList list = new ArrayList();
list.Add(i);          /* boxing   */
int j = (int)list[0]; /* unboxing */

A penalidade de usar isso é a falta de segurança e desempenho do tipo devido ao boxe e ao unboxing.

A maneira do .NET 2.0 é usar genéricos:

List<int> list = new List<int>();
list.Add(i);
int j = list[0];

O preço do boxe (no meu entender) é a necessidade de criar um objeto no heap, copiar o número inteiro da pilha alocada para o novo objeto e vice-versa para o unboxing.

Como o uso de genéricos supera isso? O número inteiro alocado à pilha permanece na pilha e sendo apontado a partir do heap (acho que não é esse o caso devido ao que acontecerá quando ficar fora do escopo)? Parece que ainda é necessário copiá-lo em outro lugar da pilha.

O que realmente está acontecendo?

questionAnswers(6)

yourAnswerToTheQuestion