Pular para o conteúdo
.NETExecução adiada e armadilhas
Módulo 01Fundamentos da Plataforma e da Linguagem

Execução adiada e armadilhas

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

A maioria dos operadores LINQ não executa na hora — só quando você itera (ou chama ToList, Count, etc.). Entender isso evita reexecução acidental e surpresas com dados que mudam.

1. Objetivos de Aprendizagem#

  • Entender execução adiada (deferred) vs imediata.
  • Reconhecer reenumeração acidental.
  • Saber quando materializar com ToList/ToArray.

2. Pré-requisitos#

  • Operadores essenciais (tópico 8.2).

3. Conceito#

  • Execução adiada: operadores como Where, Select, OrderBy não rodam quando você os escreve — eles montam uma consulta. A execução acontece quando você itera (foreach) ou chama um operador imediato.
  • Execução imediata: ToList, ToArray, Count, Sum, First... forçam a avaliação na hora.

O porquê de importar: se você itera a mesma consulta duas vezes, ela roda duas vezes. Sobre um Dictionary em memória isso é só desperdício; sobre o EF Core, são duas idas ao banco.

4. Mão na Massa#

4.1. Setup#

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

4.2. Implementação Passo a Passo#

  1. Adiada: a consulta enxerga mudanças posteriores à fonte:
C#
var numeros = new List<int> { 1, 2, 3 };
var pares = numeros.Where(n => n % 2 == 0); // ainda não executou

numeros.Add(4);
foreach (var n in pares)      // executa AGORA
    Console.WriteLine(n);     // 2, 4  (viu o 4 adicionado depois!)
  1. Reenumeração acidental:
C#
var caros = numeros.Where(n => { Console.WriteLine($"avaliando {n}"); return n > 1; });
var count = caros.Count();    // avalia uma vez
var lista = caros.ToList();   // avalia DE NOVO
  1. Materializar uma vez:
C#
var resultado = numeros.Where(n => n > 1).ToList(); // executa 1x
Console.WriteLine(resultado.Count);
foreach (var n in resultado) { /* usa sem reexecutar */ }

4.3. Executando#

Shell
dotnet run

5. Exemplo Completo#

Se você precisa do resultado mais de uma vez (contar e iterar), chame ToList() uma vez e reutilize a lista — evitando reexecutar a consulta (ou reconsultar o banco, no EF Core).

6. Boas Práticas e Armadilhas#

FaçaEvite
Materializar com ToList() quando for usar o resultado várias vezesIterar a mesma IEnumerable repetidamente sem perceber
Manter a consulta adiada quando itera só uma vezToList() prematuro que carrega tudo à memória sem necessidade
Atenção

no EF Core, chamar ToList() cedo demais traz dados desnecessários do banco; chamar tarde demais pode reconsultar. Equilíbrio é chave — materialize quando for de fato usar o resultado múltiplas vezes.

7. Segurança e Produção#

  • Reenumeração sobre IQueryable (EF Core) multiplica consultas ao banco e degrada latência sob carga. Meça e materialize conscientemente.

8. Exercícios#

  • Fácil: demonstre que uma consulta adiada "vê" um item adicionado depois.
  • Médio: conte e liste a mesma consulta e observe a dupla avaliação com um Console.WriteLine no predicado.
  • Desafio: explique a diferença entre IEnumerable<T> e IQueryable<T> quanto a onde o filtro é executado.

9. Resumo#

LINQ é majoritariamente adiado: executa ao iterar ou em operadores imediatos. Evite reenumeração acidental materializando com ToList() quando for reutilizar o resultado — crucial com EF Core.

10. Próximos Passos#

Encerramos LINQ. A seguir, delegates, lambdas e eventos — a mecânica por trás das expressões que você passou ao LINQ.

11. Referências#

08-03 — Execução adiada e armadilhas | Curso ASP.NET Core