Generics
Generics em C# são um recurso poderoso que permite escrever código flexível, seguro em relação ao tipo de dados e reutilizável. Com Generics, é possível criar classes, métodos e estruturas de dados que funcionam com diferentes tipos de dados sem a necessidade de conversão de tipos (type casting) ou duplicação de código. Isso é especialmente útil ao trabalhar com coleções como List
No desenvolvimento em C#, utilizamos Generics quando uma lógica precisa ser aplicada a múltiplos tipos de dados de forma consistente. Essa abordagem aumenta a manutenibilidade, a legibilidade do código e reduz erros em tempo de execução. Generics também se alinham aos princípios de orientação a objetos, como encapsulamento e abstração, e ajudam a criar arquiteturas de software modulares e de alto desempenho.
Neste tutorial, você aprenderá a definir classes e métodos genéricos, aplicar restrições de tipo (constraints) e usar Generics em projetos reais de C#. Além disso, abordaremos otimização de desempenho, prevenção de vazamentos de memória e padrões de design com Generics.
Exemplo Básico
textusing System;
namespace GenericsDemo
{
// Definição de uma classe genérica simples
public class Caixa<T>
{
private T conteudo;
public void Adicionar(T item)
{
conteudo = item;
}
public T Obter()
{
return conteudo;
}
}
class Program
{
static void Main(string[] args)
{
// Instanciando a classe genérica com int
Caixa<int> caixaInt = new Caixa<int>();
caixaInt.Adicionar(42);
Console.WriteLine("Conteúdo da Caixa: " + caixaInt.Obter());
// Instanciando a classe genérica com string
Caixa<string> caixaString = new Caixa<string>();
caixaString.Adicionar("Olá Mundo");
Console.WriteLine("Conteúdo da Caixa: " + caixaString.Obter());
}
}
}
Neste exemplo, a classe Caixa
O uso de Generics proporciona segurança de tipo, pois o compilador verifica se apenas o tipo especificado é utilizado. Isso elimina a necessidade de type casting, aumenta a reutilização do código e reduz erros em tempo de execução. Além disso, esta abordagem segue os princípios de OOP e as melhores práticas de desenvolvimento em C#.
Exemplo Prático
textusing System;
using System.Collections.Generic;
namespace AdvancedGenericsDemo
{
// Definição de um repositório genérico com restrição de tipo
public class Repositorio<T> where T : class
{
private List<T> itens = new List<T>();
public void Adicionar(T item)
{
if (item == null)
throw new ArgumentNullException(nameof(item), "Item não pode ser null");
itens.Add(item);
}
public T Encontrar(Predicate<T> predicado)
{
return itens.Find(predicado);
}
public void ExibirTodos()
{
foreach (var item in itens)
{
Console.WriteLine(item.ToString());
}
}
}
class Produto
{
public string Nome { get; set; }
public decimal Preco { get; set; }
public override string ToString()
{
return $"{Nome} - {Preco} R$";
}
}
class Program
{
static void Main(string[] args)
{
Repositorio<Produto> repositorioProduto = new Repositorio<Produto>();
repositorioProduto.Adicionar(new Produto { Nome = "Laptop", Preco = 7000 });
repositorioProduto.Adicionar(new Produto { Nome = "Smartphone", Preco = 4000 });
Console.WriteLine("Todos os produtos:");
repositorioProduto.ExibirTodos();
Produto produtoCaro = repositorioProduto.Encontrar(p => p.Preco > 5000);
Console.WriteLine("Produto mais caro: " + produtoCaro);
}
}
}
No exemplo avançado, Repositoriowhere T : class
, permitindo apenas tipos de referência. O método Adicionar valida se o item é null e lança uma exceção, prevenindo erros. O método Encontrar utiliza um Predicate
A classe Produto é utilizada como exemplo de aplicação real, implementando ToString para facilitar a exibição das informações. Este exemplo demonstra como Generics, princípios de OOP, algoritmos e tratamento de exceções podem ser integrados seguindo as melhores práticas do C#.
Melhores práticas e armadilhas comuns ao usar Generics em C#:
- Utilize constraints para garantir segurança de tipo.
- Evite armazenar recursos não gerenciados diretamente em generics.
- Prefira coleções genéricas internas, como List
e Dictionary\ . - Sempre verifique null e trate exceções nos métodos genéricos.
- Não generalize excessivamente suas classes e métodos.
- Atente-se ao tipo real durante depuração.
- Evite boxing/unboxing desnecessário para otimização de desempenho.
- Valide entradas e proteja dados sensíveis para segurança.
📊 Tabela de Referência
C# Element/Concept | Description | Usage Example |
---|---|---|
Classe Genérica | Classe que pode trabalhar com múltiplos tipos | public class Caixa<T> { T conteudo; } |
Método Genérico | Método que processa diferentes tipos de dados | public T ObterItem<T>(T item) { return item; } |
Constraints | Imposição de restrições ao tipo | where T : class, new() |
List<T> | Coleção genérica de elementos | List<int> numeros = new List<int>(); |
Dictionary\<TKey,TValue> | Coleção genérica chave-valor | Dictionary\<string,int> idades = new Dictionary\<string,int>(); |
Predicate<T> | Delegate para filtragem ou busca | itens.Find(p => p.Preco > 5000); |
Resumo e próximos passos:
Generics em C# permitem criar código seguro, reutilizável e eficiente. Utilizando classes e métodos genéricos, constraints e padrões de design, você pode construir arquiteturas modulares com alto desempenho e menos erros de tempo de execução.
Próximos tópicos recomendados incluem Stack
🧠 Teste Seu Conhecimento
Teste seu Conhecimento
Teste sua compreensão deste tópico com questões práticas.
📝 Instruções
- Leia cada pergunta cuidadosamente
- Selecione a melhor resposta para cada pergunta
- Você pode refazer o quiz quantas vezes quiser
- Seu progresso será mostrado no topo