Generics (Classes e Métodos)
Parte da seção Programação Orientada a Objetos do Journey de C# da Coddy. Lição 42 de 70.
Os genéricos permitem escrever classes e métodos que funcionam com qualquer tipo de dado, mantendo a segurança de tipos. Em vez de escrever classes separadas para IntList, StringList e DoubleList, você escreve uma única classe genérica que lida com todos eles.
Uma classe genérica usa um parâmetro de tipo, geralmente chamado T, delimitado por colchetes angulares:
public class Box<T>
{
private T content;
public void Store(T item) => content = item;
public T Retrieve() => content;
}
// Uso com diferentes tipos
Box<int> intBox = new Box<int>();
intBox.Store(42);
Box<string> stringBox = new Box<string>();
stringBox.Store("Hello");Quando você cria Box<int>, o compilador substitui cada T por int. Isso oferece verificação de tipos em tempo de compilação — você não pode armazenar acidentalmente uma string em uma caixa de int.
Métodos genéricos funcionam de forma semelhante, permitindo que um único método opere com diferentes tipos:
public static void Swap<T>(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}
int x = 1, y = 2;
Swap(ref x, ref y); // x=2, y=1O compilador infere o tipo a partir dos argumentos, então você não precisa escrever Swap<int> explicitamente. Os genéricos são a base de coleções como List<T> e Dictionary<TKey, TValue>, permitindo código reutilizável e seguro quanto aos tipos.
Desafio
FácilVamos criar um sistema genérico Storage<T> que pode armazenar e gerenciar itens de qualquer tipo. Você criará uma classe de contêiner reutilizável que demonstra o poder dos genéricos: escreva uma vez e use com inteiros, strings ou qualquer outro tipo!
Você organizará seu código em dois arquivos:
Storage.cs: Crie uma classe genéricaStorage<T>no namespaceDataStorage. Seu contêiner de armazenamento deve:- Ter um array privado do tipo
Tpara armazenar itens e uma propriedadeCountque acompanhe quantos itens estão armazenados - Aceitar uma capacidade no construtor para inicializar o array interno
- Ter um método
Add(T item)que adiciona um item se houver espaço - Ter um método
Get(int index)que retorna o item no índice especificado - Ter um método
GetAll()que retorna todos os itens armazenados unidos por", "
- Ter um array privado do tipo
Program.cs: No seu arquivo principal, demonstre sua classe genérica funcionando com dois tipos diferentes. Crie umStorage<int>e umStorage<string>, adicione itens a cada um e mostre que a mesma classe funciona perfeitamente com ambos os tipos.
Você receberá quatro entradas:
- Primeiro inteiro a armazenar
- Segundo inteiro a armazenar
- Primeira string a armazenar
- Segunda string a armazenar
Crie um armazenamento de inteiros com capacidade 5 e um armazenamento de strings com capacidade 5. Adicione os dois inteiros ao armazenamento de inteiros e as duas strings ao armazenamento de strings.
Imprima a saída neste formato:
Int storage: {GetAll()}
Int count: {Count}
First int: {Get(0)}
String storage: {GetAll()}
String count: {Count}
First string: {Get(0)}Por exemplo, se as entradas forem 42, 100, Hello e World, a saída deverá ser:
Int storage: 42, 100
Int count: 2
First int: 42
String storage: Hello, World
String count: 2
First string: HelloObserve como você escreve a classe Storage<T> uma única vez, mas ela funciona perfeitamente tanto com int quanto com string — essa é a magia dos genéricos! O compilador garante a segurança de tipos, então você não pode adicionar acidentalmente uma string ao seu armazenamento de inteiros.
Experimente você mesmo
using System;
using DataStorage;
class Program
{
public static void Main(string[] args)
{
// Leia as entradas
int num1 = Convert.ToInt32(Console.ReadLine());
int num2 = Convert.ToInt32(Console.ReadLine());
string str1 = Console.ReadLine();
string str2 = Console.ReadLine();
// TODO: Crie um Storage<int> com capacidade 5
// TODO: Adicione os dois inteiros ao armazenamento de inteiros
// TODO: Crie um Storage<string> com capacidade 5
// TODO: Adicione as duas strings ao armazenamento de strings
// TODO: Imprima a saída no formato exigido
// Int storage: {GetAll()}
// Contagem de int: {Count}
// Primeiro int: {Get(0)}
// String storage: {GetAll()}
// String count: {Count}
// First string: {Get(0)}
}
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de POO
Arquivos ExternosNamespaces e DiretivasIntrodução a Classes e ObjetosA Palavra-chave 'this'Métodos e ParâmetrosCampos vs PropriedadesConstrutoresInicializadores de ObjetosRecapitulação - Calculadora Simples4Herança
Sintaxe Básica de Herança (:)A Palavra-chave 'base'Palavras-chave Virtual e OverrideClasses SeladasA Classe Base 'object'Recapitulação - Hierarquia de Funcionários7Recursos Avançados
Sobrecarga de OperadoresIndexadores (this[])Sobrescrita de ToString()Métodos de ExtensãoRecapitulação - Lista Personalizada10Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoSingleton Thread-SafePadrão FactoryPadrão Observer (Eventos)Padrão Strategy2Propriedades e Membros Estáticos
Propriedades AutoimplementadasPropriedades de Apenas Leitura/EscritaCampos e Métodos EstáticosClasses EstáticasMembros com Corpo de Expressão5Polimorfismo e Interfaces
Polimorfismo: Compilação vs ExecuçãoInterface vs Classe AbstrataMúltiplas InterfacesInterfaces ExplícitasUpcasting e DowncastingRecapitulação - Calculadora de Formas8Conceitos Avançados de POO
Composição sobre HerançaGenerics (Classes e Métodos)Delegates e EventosAtributos e ReflectionIDisposable e a Instrução usingFundamentos de Injeção de Dependência11Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão Composite3Arquitetura de Classes
Dados de Instância vs EstáticosPalavras-chave 'readonly' e 'const'Campos de SuporteRecapitulação - Gerenciador de Conta Bancária6Encapsulamento
Modificadores de AcessoPropriedades para EncapsulamentoImplementação de Ocultação de DadosPadrões de ImutabilidadeRecapitulação - Registros de Estudantes9Argumentos Variáveis
A Palavra-chave 'params'Parâmetros OpcionaisArgumentos NomeadosSobrecarga de MétodosPratique por conta própria: Compilador de C# online