Pular para o conteúdo
.NETIEnumerable, ICollection e IReadOnlyList
Módulo 01Fundamentos da Plataforma e da Linguagem

IEnumerable, ICollection e IReadOnlyList

intermediario 24 min de leitura·Atualizado · .NET 9
Resumo

Essas interfaces descrevem "o que dá para fazer" com uma coleção. Expor a mais restrita que atende (ex.: IEnumerable<T> para só iterar) comunica intenção e evita mutações indesejadas.

1. Objetivos de Aprendizagem#

  • Diferenciar as principais interfaces de coleção.
  • Escolher o tipo de retorno certo para métodos.
  • Entender o impacto na iteração e na mutabilidade.

2. Pré-requisitos#

  • Coleções essenciais (tópico 7.1).

3. Conceito#

Hierarquia (simplificada), da mais restrita à mais rica:

  • IEnumerable<T>: só permite iterar (foreach). Base do LINQ.
  • IReadOnlyCollection<T>: iterar + Count.
  • IReadOnlyList<T>: o anterior + acesso por índice ([i]), somente leitura.
  • ICollection<T>: permite modificar (Add, Remove, Clear).
  • IList<T>: modificar + índice.

O porquê de expor a interface certa: um método que retorna IEnumerable<T> deixa claro "apenas percorra"; retornar List<T> convida o chamador a mutar a coleção interna.

4. Mão na Massa#

4.1. Setup#

Shell
dotnet new console -n Catalog.Interfaces
cd Catalog.Interfaces

4.2. Implementação Passo a Passo#

  1. Retornar IEnumerable<T> (só leitura/iteração):
C#
public class Catalogo
{
    private readonly List<string> _itens = new() { "Mouse", "Teclado" };

    // O chamador só pode iterar, não mutar a lista interna
    public IReadOnlyList<string> Itens => _itens;

    public IEnumerable<string> EmPromocao() =>
        _itens.Where(i => i.StartsWith("M"));
}
  1. Consumo:
C#
var c = new Catalogo();
foreach (var item in c.Itens)          // itera
    Console.WriteLine(item);
// c.Itens.Add("x");  // NÃO compila: IReadOnlyList não expõe Add

4.3. Executando#

Shell
dotnet run

5. Exemplo Completo#

Expor IReadOnlyList<string> Itens protege a lista interna: o mundo externo lê e itera, mas não altera o estado do Catalogo por fora.

6. Boas Práticas e Armadilhas#

FaçaEvite
Retornar a interface mais restrita que atendeExpor List interna e permitir mutação externa
Aceitar IEnumerable em parâmetros (flexível)Exigir List sem necessidade
Materializar com ToList() quando for iterar várias vezesReenumerar uma query cara repetidamente
Atenção

IEnumerable<T> pode ser "preguiçoso" (avaliação adiada). Iterar duas vezes pode reexecutar a consulta — veremos isso no módulo de LINQ.

7. Segurança e Produção#

  • Expor coleções somente-leitura evita que outras partes do sistema corrompam o estado interno de um objeto — menos bugs de efeito colateral.

8. Exercícios#

  • Fácil: troque um retorno List<T> por IReadOnlyList<T>.
  • Médio: escreva um método que aceita IEnumerable<int> e soma os valores.
  • Desafio: demonstre uma reenumeração acidental e conserte com ToList().

9. Resumo#

Prefira a interface mais restrita que atende: IEnumerable<T> para iterar, IReadOnlyList<T> para ler por índice, ICollection/IList quando precisar mutar. Isso comunica intenção e protege o estado interno.

10. Próximos Passos#

Com coleções dominadas, entramos em LINQ para consultá-las.

11. Referências#

07-03 — IEnumerable, ICollection e IReadOnlyList | Curso ASP.NET Core