Benefícios dos genéricos (Guia de Programação em C#)Benefits of Generics (C# Programming Guide)

Os genéricos oferecem a solução para uma limitação em versões anteriores do Common Language Runtime da linguagem C# em que a generalização é realizada por tipos de conversão de e para o tipo base universal Object.Generics provide the solution to a limitation in earlier versions of the common language runtime and the C# language in which generalization is accomplished by casting types to and from the universal base type Object. Ao criar uma classe genérica, é possível criar uma coleção fortemente tipada em tempo de compilação.By creating a generic class, you can create a collection that is type-safe at compile-time.

As limitações do uso de classes de coleção não genéricas não podem ser demonstradas ao escrever um pequeno programa que use a classe de coleção ArrayList da biblioteca de classes do .NET.The limitations of using non-generic collection classes can be demonstrated by writing a short program that uses the ArrayList collection class from the .NET class library. Uma instância da classe ArrayList pode armazenar qualquer referência ou tipo de valor.An instance of the ArrayList class can store any reference or value type.

// The .NET Framework 1.1 way to create a list:
System.Collections.ArrayList list1 = new System.Collections.ArrayList();
list1.Add(3);
list1.Add(105);

System.Collections.ArrayList list2 = new System.Collections.ArrayList();
list2.Add("It is raining in Redmond.");
list2.Add("It is snowing in the mountains.");

Porém, essa conveniência gera um custo.But this convenience comes at a cost. Qualquer tipo de referência ou valor que é adicionado a um ArrayList é implicitamente upcast para Object.Any reference or value type that is added to an ArrayList is implicitly upcast to Object. Se os itens forem tipos de valor, será necessário que eles sejam convertidos ao serem adicionados à lista e desconvertidos ao serem recuperados.If the items are value types, they must be boxed when they are added to the list, and unboxed when they are retrieved. Tanto a conversão quanto as operações de conversão boxing e unboxing diminuem o desempenho; o efeito das conversões boxing e unboxing podem ser muito significativos em cenários em que é necessário iterar em coleções grandes.Both the casting and the boxing and unboxing operations decrease performance; the effect of boxing and unboxing can be very significant in scenarios where you must iterate over large collections.

A outra limitação é a falta de verificação de tipo em tempo de compilação, pois uma ArrayList converte tudo para Object; não é possível evitar que o código cliente faça algo como isto no tempo de compilação:The other limitation is lack of compile-time type checking; because an ArrayList casts everything to Object, there is no way at compile-time to prevent client code from doing something such as this:

System.Collections.ArrayList list = new System.Collections.ArrayList();
// Add an integer to the list.
list.Add(3);
// Add a string to the list. This will compile, but may cause an error later.
list.Add("It is raining in Redmond.");

int t = 0;
// This causes an InvalidCastException to be returned.
foreach (int x in list)
{
    t += x;
}

Embora seja perfeitamente aceitável e por vezes intencional, se você estiver criando uma coleção heterogênea, é mais provável que combinar cadeias de caracteres e ints em uma única ArrayList seja um erro de programação e esse erro não será detectado até o tempo de execução.Although perfectly acceptable and sometimes intentional if you are creating a heterogeneous collection, combining strings and ints in a single ArrayList is more likely to be a programming error, and this error will not be detected until runtime.

Nas versões 1.0 e 1.1 da linguagem C#, é possível evitar os perigos do código generalizado em classes de coleção da biblioteca de classes base do .NET Framework somente pela gravação de suas próprias coleções de tipo específico.In versions 1.0 and 1.1 of the C# language, you could avoid the dangers of generalized code in the .NET Framework base class library collection classes only by writing your own type specific collections. Claro, como tal classe não é reutilizável para mais de um tipo de dados, os benefícios da generalização serão perdidos e será necessário gravar novamente a classe para cada tipo que será armazenado.Of course, because such a class is not reusable for more than one data type, you lose the benefits of generalization, and you have to rewrite the class for each type that will be stored.

O que ArrayList e outras classes semelhantes precisam é uma maneira de o código cliente especificar, em uma base por instância, o tipo de dados específico que pretende usar.What ArrayList and other similar classes really need is a way for client code to specify, on a per-instance basis, the particular data type that they intend to use. Isso eliminaria a necessidade do upcast para Object e possibilitaria ao compilador a realização da verificação de tipo.That would eliminate the need for the upcast to Object and would also make it possible for the compiler to do type checking. Em outras palavras, ArrayList precisa de um parâmetro de tipo.In other words, ArrayList needs a type parameter. Isso é exatamente o que os genéricos oferecem.That is exactly what generics provide. Na coleção genérica List<T>, no namespace System.Collections.Generic, a mesma operação de adição de itens à coleção é semelhante a:In the generic List<T> collection, in the System.Collections.Generic namespace, the same operation of adding items to the collection resembles this:

// The .NET Framework 2.0 way to create a list
List<int> list1 = new List<int>();

// No boxing, no casting:
list1.Add(3);

// Compile-time error:
// list1.Add("It is raining in Redmond.");

Para código cliente, a única sintaxe adicionada com List<T> em comparação com ArrayList é o argumento de tipo na declaração e na instanciação.For client code, the only added syntax with List<T> compared to ArrayList is the type argument in the declaration and instantiation. Como compensação por essa complexidade na codificação, é possível criar uma lista que não só é mais segura do que ArrayList, mas também é significativamente mais rápida, especialmente quando os itens da lista são tipos de valor.In return for this slightly more coding complexity, you can create a list that is not only safer than ArrayList, but also significantly faster, especially when the list items are value types.

Consulte tambémSee Also