Menu
Coddy logo textTech

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.

Generics permitem que você escreva 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, tipicamente chamado T, envolto em colchetes angulares:

public class Box<T>
{
    private T content;
    
    public void Store(T item) => content = item;
    public T Retrieve() => content;
}

// Uso com tipos diferentes
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 fornece verificação de tipo em tempo de compilação - você não pode armazenar acidentalmente uma string em uma caixa int.

Métodos genéricos funcionam de forma semelhante, permitindo que um único método opere em 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=1

O compilador infere o tipo a partir dos argumentos, então você não precisa escrever Swap<int> explicitamente. Genéricos são a base de coleções como List<T> e Dictionary<TKey, TValue>, permitindo código reutilizável e com segurança de tipos.

challenge icon

Desafio

Fácil

Vamos criar um sistema genérico de Storage<T> que possa 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érica Storage<T> no namespace DataStorage. Seu contêiner de armazenamento deve:
    • Ter um array privado do tipo T para armazenar itens e uma propriedade Count que acompanhe quantos itens estão armazenados
    • Aceitar uma capacidade em seu construtor para inicializar o array interno
    • Ter um método Add(T item) que adicione um item se houver espaço
    • Ter um método Get(int index) que retorne o item no índice especificado
    • Ter um método GetAll() que retorne todos os itens armazenados unidos por ", "
  • Program.cs: No seu arquivo principal, demonstre sua classe genérica funcionando com dois tipos diferentes. Crie um Storage<int> e um Storage<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 ser armazenado
  • Segundo inteiro a ser armazenado
  • Primeira string a ser armazenada
  • Segunda string a ser armazenada

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: Hello

Observe 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, portanto 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)
    {
        // Ler as entradas
        int num1 = Convert.ToInt32(Console.ReadLine());
        int num2 = Convert.ToInt32(Console.ReadLine());
        string str1 = Console.ReadLine();
        string str2 = Console.ReadLine();

        // TODO: Criar um Storage<int> com capacidade 5
        
        // TODO: Adicionar os dois inteiros ao armazenamento de inteiros
        
        // TODO: Criar um Storage<string> com capacidade 5
        
        // TODO: Adicionar as duas strings ao armazenamento de strings
        
        // TODO: Imprimir a saída no formato exigido
        // Int storage: {GetAll()}
        // Int count: {Count}
        // First int: {Get(0)}
        // String storage: {GetAll()}
        // String count: {Count}
        // First string: {Get(0)}
    }
}
quiz iconTeste seus conhecimentos

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

Pratique por conta própria: Compilador de C# online