Generics em C#: para que servem e como usar
\n\nAo desenvolver em C#, mais cedo ou mais tarde todos se deparam com uma situação em que o mesmo algoritmo precisa ser aplicado a diferentes tipos de dados. Antes, para isso, era necessário escrever várias versões do mesmo método ou usar o tipo object, o que levava à perda de desempenho e ao risco de erros. A solução para esse problema são os Generics (tipos genéricos). Neste artigo, vamos entender o que são generics, para que servem e como usá-los corretamente em C#.
O que são Generics em C#?
\n\nGenerics (generalizações) são um mecanismo da linguagem C# que permite criar classes, métodos, interfaces e delegates que trabalham com diferentes tipos de dados, sem perder a tipagem forte. Em vez de escrever código para cada tipo separadamente, você cria um modelo universal que substitui o tipo necessário durante a compilação.
\n\nImagine que você precisa escrever um método para trocar os valores de duas variáveis. Sem generics, você teria que criar métodos separados para int, string, double, etc. Com generics, você escreve um único método que funciona com qualquer tipo.
Aqui está um exemplo simples de declaração de um método genérico:
\n\npublic void Swap<T>(ref T a, ref T b)\n{\n T temp = a;\n a = b;\n b = temp;\n}\n\nAqui, <T> é o parâmetro de tipo. A letra T é uma notação comum (de Type), mas você pode usar qualquer nome. Ao chamar o método, você especifica o tipo concreto:
int x = 5, y = 10;\nSwap<int>(ref x, ref y);\n// Agora x = 10, y = 5\n\nstring first = "Olá", second = "Mundo";\nSwap<string>(ref first, ref second);\n// Agora first = "Mundo", second = "Olá"\n\nPara que servem os Generics: principais vantagens
\n\nO uso de generics oferece várias vantagens importantes que tornam o código melhor e mais seguro.
\n\n1. Segurança de tipos (Type Safety)
\nAo contrário do uso de object, os generics verificam os tipos em tempo de compilação. Você não conseguirá passar acidentalmente uma string onde se espera um número. O compilador apontará o erro imediatamente.
2. Desempenho
\nAo usar object, ocorre o boxing (empacotamento) de tipos por valor (int, double, struct) em um tipo por referência e o unboxing (desempacotamento) reverso. Essas são operações custosas. Os generics eliminam completamente esses processos, pois o compilador gera código especializado para cada tipo.
3. Reutilização de código
\nVocê não precisa escrever o mesmo algoritmo para tipos diferentes. Uma única classe ou método genérico pode funcionar com milhares de tipos diferentes.
\n\n4. Legibilidade e facilidade de manutenção
\nO código fica mais limpo e compreensível. Você vê claramente com quais tipos o método ou classe trabalha, e a lógica é separada dos tipos de dados específicos.
\n\nComo usar Generics: exemplos práticos
\n\nVamos analisar alguns cenários reais de uso de generics em C#.
\n\nClasses genéricas
\nO exemplo mais comum são as coleções. Em vez de criar sua própria classe para armazenar uma lista de números, strings ou objetos personalizados, você usa List<T>:
List<int> numbers = new List<int>();\nnumbers.Add(1);\nnumbers.Add(2);\n\nList<string> names = new List<string>();\nnames.Add("Alice");\nnames.Add("Bob");\n\n// Sua própria classe genérica\npublic class Repository<T>\n{\n private List<T> _items = new List<T>();\n\n public void Add(T item) => _items.Add(item);\n public T Get(int index) => _items[index];\n}\n\nRepository<int> intRepo = new Repository<int>();\nintRepo.Add(100);\nint value = intRepo.Get(0); // 100\n\nMétodos genéricos
\nOs métodos podem ser genéricos mesmo dentro de classes comuns:
\n