Em aplicações que lidam com grandes volumes de dados, pode ser necessário começar a retornar resultados antes que todo o processamento seja concluído. Isso é especialmente útil para evitar o consumo excessivo de memória e melhorar o desempenho da aplicação. No C#, a palavra-chave “yield” é uma ferramenta bastante útil para lidar com essa necessidade, permitindo a criação de iteradores que geram valores sob demanda. Neste artigo exploraremos como “yield return” e “yield break” funcionam, sua aplicação prática e os benefícios no gerenciamento de coleções grandes.
O que é yield?
Em C#, “yield” é usado dentro de métodos iteradores para retornar elementos um por um, sem precisar armazenar todos os itens na memória. A palavra-chave “yield return” permite que um método produza uma sequência de valores sob demanda, enquanto “yield break” encerra a iteração antecipadamente.
Como yield funciona internamente em métodos iteradores
Quando um método contém “yield return”, o compilador gera automaticamente um iterador que preserva o estado entre as chamadas subsequentes. Isso significa que os valores são calculados sob demanda, permitindo uma iteração eficiente em memória.
yield return
Para entendermos melhor vamos ver um exemplo prático:
foreach (var numero in GeradorNumeros(5))
{
Console.WriteLine(numero);
}
IEnumerable GeradorNumeros(int quantidade)
{
for (int i = 1; i <= quantidade; i++)
{
yield return i;
}
}
No código acima foi criado o método “GeradorNumeros”, que recebe um número inteiro “quantidade” e retorna uma sequência de números de 1 até a quantidade informada. Dentro do “for”, cada valor de “i” é retornado usando “yield return i;”, o que significa que o método pausa a execução e retorna o valor atual.
O “foreach” percorre essa sequência e imprime cada número no console. A cada iteração, o método “GeradorNumeros” continua de onde parou, sem recriar a sequência.
yield break
O “yield break” interrompe a execução do iterador imediatamente, encerrando a iteração sem retornar mais elementos. Isso é útil quando uma condição específica determina que a sequência deve ser interrompida.
foreach (var numero in GeradorNumeroComBreak(5))
{
Console.WriteLine(numero);
}
IEnumerable GeradorNumeroComBreak(int maximo)
{
for (int i = 1; i <= maximo; i++)
{
if (i == 4)
yield break;
yield return i;
}
}
O método “GeradorNumeroComBreak” gera uma sequência de números de “1” até “maximo”. O “for” itera os números e retorna cada um deles usando “yield return”. Quando “i” atinge o valor 4, “yield break” é chamado, encerrando a iteração imediatamente. O resultado da iteração será a exibição dos números 1, 2 e 3, pois a execução será interrompida antes de retornar o número 4.
Acelere a sua carreira conosco!
Se você é Desenvolvedor .NET Júnior e quer acelerar sua carreira até nível Pleno com salário de R$7k+, ou mesmo busca a primeira vaga, conheça a Mentoria .NET Start: Clique aqui
Se é Desenvolvedor .NET Pleno ou Sênior e quer virar referência técnica em sua equipe e mercado, com salário de R$10k+, conheça a Mentoria .NET Expert: Clique aqui
Vantagens e desvantagens do uso de yield
Vantagens:
- Reduz o uso de memória ao gerar elementos sob demanda.
- Facilita a implementação de iteradores complexos.
- Melhora a eficiência ao processar coleções grandes.
- Evita a necessidade de criar listas intermediárias.
Desvantagens:
- Pode ser menos eficiente quando todos os elementos precisam ser armazenados na memória.
- Difícil depurar devido ao comportamento lazy.
- Métodos iteradores não podem ter parâmetros ref ou out.
Conclusão
O uso do yield no C# permite criar iteradores eficientes e evitar o consumo excessivo de memória. Ao utilizar yield, você pode otimizar a iteração de grandes coleções e sequências dinâmicas de forma simples e elegante. Experimente aplicar yield em seus projetos para melhorar a eficiência e a legibilidade do seu código!