Classes e métodos genéricos
Genéricos apresentam o conceito de parâmetros de tipo ao .NET, que possibilitam a criação de classes e métodos que adiam a especificação de um ou mais tipos até que a classe ou método seja declarado e instanciado pelo código do cliente. Por exemplo, ao usar um parâmetro de tipo genérico T
, você pode escrever uma única classe que outro código de cliente pode usar sem incorrer o custo ou risco de conversões de runtime ou operações de conversão boxing, conforme mostrado aqui:
// Declare the generic class.
public class GenericList<T>
{
public void Add(T input) { }
}
class TestGenericList
{
private class ExampleClass { }
static void Main()
{
// Declare a list of type int.
GenericList<int> list1 = new GenericList<int>();
list1.Add(1);
// Declare a list of type string.
GenericList<string> list2 = new GenericList<string>();
list2.Add("");
// Declare a list of type ExampleClass.
GenericList<ExampleClass> list3 = new GenericList<ExampleClass>();
list3.Add(new ExampleClass());
}
}
As classes e métodos genéricos combinam a capacidade de reutilização, a segurança de tipos e a eficiência de uma maneira que suas contrapartes não genéricas não conseguem. Os genéricos são usados com mais frequência com coleções e com os métodos que operam nelas. O namespace System.Collections.Generic contém várias classes de coleção de base genérica. As coleções não-genéricas, como ArrayList não são recomendadas e são mantidas para fins de compatibilidade. Para saber mais, confira Genéricos no .NET.
Você também pode criar tipos e métodos genéricos personalizados para fornecer suas próprias soluções e padrões de design generalizados que sejam fortemente tipados e eficientes. O exemplo de código a seguir mostra uma classe de lista vinculada genérica simples para fins de demonstração. (Na maioria dos casos, você deve usar a classe List<T> fornecida pelo .NET em vez de criar sua própria.) O parâmetro de tipo T
é usado em vários locais em que um tipo concreto normalmente seria usado para indicar o tipo do item armazenado na lista. Ele é usado das seguintes maneiras:
- Como o tipo de um parâmetro de método no método
AddHead
. - Como o tipo de retorno da propriedade
Data
na classeNode
aninhada. - Como o tipo de
data
do membro particular na classe aninhada.
T
está disponível para a classe aninhada Node
. Quando GenericList<T>
é instanciada com um tipo concreto, por exemplo como um GenericList<int>
, cada ocorrência de T
será substituída por int
.
// type parameter T in angle brackets
public class GenericList<T>
{
// The nested class is also generic on T.
private class Node
{
// T used in non-generic constructor.
public Node(T t)
{
next = null;
data = t;
}
private Node? next;
public Node? Next
{
get { return next; }
set { next = value; }
}
// T as private member data type.
private T data;
// T as return type of property.
public T Data
{
get { return data; }
set { data = value; }
}
}
private Node? head;
// constructor
public GenericList()
{
head = null;
}
// T as method parameter type:
public void AddHead(T t)
{
Node n = new Node(t);
n.Next = head;
head = n;
}
public IEnumerator<T> GetEnumerator()
{
Node? current = head;
while (current != null)
{
yield return current.Data;
current = current.Next;
}
}
}
O exemplo de código a seguir mostra como o código cliente usa a classe GenericList<T>
genérica para criar uma lista de inteiros. Ao simplesmente alterar o argumento de tipo, o código a seguir poderia facilmente ser modificado para criar listas de cadeias de caracteres ou qualquer outro tipo personalizado:
class TestGenericList
{
static void Main()
{
// int is the type argument
GenericList<int> list = new GenericList<int>();
for (int x = 0; x < 10; x++)
{
list.AddHead(x);
}
foreach (int i in list)
{
System.Console.Write(i + " ");
}
System.Console.WriteLine("\nDone");
}
}
Visão geral de genéricos
- Use tipos genéricos para maximizar a reutilização de código, o desempenho e a segurança de tipo.
- O uso mais comum de genéricos é para criar classes de coleção.
- A biblioteca de classes do .NET contém várias classes de coleção de genéricos no namespace System.Collections.Generic. As coleções genéricas devem ser usadas sempre que possível, em vez de classes como ArrayList no namespace System.Collections.
- Você pode criar suas próprias interfaces genéricas, classes, métodos, eventos e delegados.
- Classes genéricas podem ser restringidas para habilitar o acesso aos métodos em tipos de dados específicos.
- Informações sobre os tipos que são usados em um tipo de dados genérico podem ser obtidas no tempo de execução por meio de reflexão.
Especificação da linguagem C#
Para obter mais informações, consulte a Especificação da linguagem C#.