Compartilhar via


Benefits of Generics (C# Programming Guide)

Os genéricos proporcionam a solução a uma limitação nas versões anteriores do common language runtime e a linguagem de C# no qual a generalização é realizada por tipos de projeção para e do tipo base universal Object. Criando uma classe genérica, você pode criar uma coleção que é fortemente tipada em tempo de compilação.

As limitações do uso de classes de coleção não genéricas que podem ser demonstradas escrevendo um pequeno programa que usa a ArrayList a classe de coleção da.NET Framework class library. ArrayListé uma classe de coleção altamente conveniente que pode ser usada para armazenar qualquer tipo de referência ou valor sem modificação.

// 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.");

Mas essa conveniência a um custo. Qualquer tipo de referência ou valor é adicionado a uma ArrayList é implicitamente elevado para Object. Se os itens forem tipos valorados, eles devem ser boxed quando estiverem adicionados à lista e unboxed quando eles são recuperados. A projeção e operações de boxing e unboxing diminuir o desempenho; o efeito de boxing e unboxing pode ser muito significativo em cenários onde você deve iterar grandes coleções.

A outra limitação é a falta de tipo em tempo de compilação verificação; porque um ArrayList projeta tudo para Object, não há nenhuma maneira em tempo de compilação para impedir que o código de cliente fazendo algo, como:

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 perfeitamente aceitável e às vezes intencional, se você estiver criando um conjunto heterogêneo, combinando seqüências e ints em um único ArrayList tem mais probabilidade de ser um erro de programação, e esse erro não será detectado até o runtime.

Nas versões 1.0 e 1.1 da linguagem C#, você poderia evitar os perigos do código generalizado em classes de coleção da biblioteca de classes base do .NET Framework apenas escrevendo suas próprias coleções específicas do tipo. Claro, porque essa classe não é reutilizável para mais de um tipo de dados, perder os benefícios da generalização e ter reescrever a classe para cada tipo que será armazenada.

O que ArrayList e outras classes semelhantes realmente precisam é uma forma de código do cliente especificar, em uma base por instância, o tipo de dados específico que pretendem usar. Que eliminaria a necessidade de elevação para T:System.Object e seria também tornam possível para o compilador de verificação de tipo. Em outras palavras, ArrayList precisa de um parâmetro de tipo. É exatamente o que os genéricos proporcionam. No genérico List<T> coleção, na N:System.Collections.Generic namespace, a mesma operação de adicionar itens à coleção lembra isto:

// 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.");

Código do cliente, a única adicionado sintaxe com List<T> em comparação com o ArrayList é o argumento de tipo na declaração e instanciação. Por essa codificação ligeiramente mais complexidade, você pode criar uma lista que não é apenas mais segura do que ArrayList, mas também significativamente mais rápido, especialmente quando os itens de lista são tipos de valor.

Consulte também

Referência

Introduction to Generics (C# Programming Guide)

System.Collections.Generic

Boxing e Unboxing (C# guia de programação)

Conceitos

C# Programming Guide

Outros recursos

Coleções de melhores práticas