C#
- Usando yield return
![]() |
Neste artigo vamos recordar para que serve e como usar a palavra chave yield e yield return na linguagem C#. |
A palavra-chave "yield" é usada em um método para criar um iterador. Um iterador permite que você percorra uma coleção de itens de forma conveniente, fornecendo um item por vez, conforme necessário, em vez de carregar todos os itens na memória de uma vez.
O "yield" é usado em conjunto com a declaração "yield return" para retornar um valor da sequência sendo iterada. Quando o método encontra a declaração "yield return", ele retorna o valor especificado e pausa a execução do método até que o próximo valor seja solicitado. Isso permite que a iteração ocorra sob demanda, economizando recursos de memória.
A seguir temos um exemplo básico do uso de yield em um projeto Console criado no VS 2022 Community usando o C# 11 e o recurso Top Level Stataments:
Console.WriteLine("\nUsando
yield return\n"); foreach (var numero in GetNumeros()){ Console.WriteLine(numero); } Console.ReadKey(); static IEnumerable<int> GetNumeros(){ yield return 1; yield return 2; yield return 3; } |
Neste exemplo, o método GetNumeros retorna um iterador de IEnumerable<int>. A cada chamada de yield return, um número é retornado da sequência. O método Main usa um loop foreach para iterar sobre os números retornados e imprimir cada um deles.
Quando o método GetNumeros é chamado, ele não retorna imediatamente todos os números de uma vez. Em vez disso, ele retorna um número de cada vez, pausando a execução após cada yield return até que o próximo número seja solicitado, e, isso permite que você itere sobre a sequência de números sem carregar todos eles na memória ao mesmo tempo.
Assim, a palavra-chave "yield" é uma ferramenta poderosa para lidar com coleções grandes ou sequências infinitas de dados, permitindo que você itere sobre eles de forma eficiente e sob demanda.
Como o yield funciona ?
Quando o método é chamado, ele não é executado imediatamente até o final. Em vez disso, a execução do método é pausada no ponto onde ocorre a declaração "yield return" e um valor é retornado. Esse valor é retornado como parte da sequência que está sendo iterada.
Quando o iterador é percorrido, seja com um loop foreach ou manualmente usando o método GetEnumerator() e MoveNext(), o método é executado até encontrar a próxima declaração "yield return". Nesse ponto, o valor especificado é retornado e a execução do método é pausada novamente.
Esse processo de pausar e continuar a execução do método ocorre até que não haja mais declarações "yield return" para serem encontradas. Quando o método atinge o final ou encontra uma declaração "yield break", a iteração é finalizada.
A palavra-chave "yield" é uma forma conveniente de criar um iterador em C#, permitindo que você crie sequências de dados de forma eficiente e com uso mínimo de memória, pois os valores são retornados sob demanda, à medida que são solicitados. Isso é especialmente útil para lidar com grandes conjuntos de dados ou sequências infinitas.
Para usar a palavra-chave "yield", existem alguns requisitos a serem atendidos:
Exemplo prático
Como
exemplo prático que ilustra o uso de yield vamos criar um
iterador que retorna apenas os arquivos com uma determinada extensão
em um diretório específico:
Console.WriteLine("\nObtendo
os arquivos de uma pasta\n"); Console.WriteLine( "Informe o caminho da pasta: (Ex: c:\\dados ");var caminho = Console.ReadLine(); Console.WriteLine( "Informe a extensão dos arquivos (Ex: .txt ");var extensao = Console.ReadLine(); Console.WriteLine( "\nArquivos encontrados\n");foreach (var file in GetArquivosComExtensao(@caminho, extensao)) { Console.WriteLine(file); } Console.ReadKey(); static IEnumerable<string> GetArquivosComExtensao(string directoryPath, string fileExtension){ foreach (var file in Directory.GetFiles(directoryPath)) { if (Path.GetExtension(file).Equals(fileExtension, StringComparison.OrdinalIgnoreCase)) { yield return file; } } } |
Executando o projeto iremos obter:
Neste exemplo, o método GetArquivosComExtensao retorna um iterador de IEnumerable<string>. Ele recebe dois parâmetros: caminho, que é o caminho para o diretório que queremos pesquisar, e extensao, que é a extensão dos arquivos que queremos encontrar.
Dentro do método, usamos o método Directory.GetFiles para obter uma lista de todos os arquivos no diretório especificado. Em seguida, percorremos cada arquivo retornado e verificamos se a extensão do arquivo corresponde à extensão desejada. Se corresponder, usamos a declaração "yield return" para retornar o caminho completo do arquivo.
A seguir definimos o diretório caminho e a extensão extensao para buscar arquivos no diretório especificado com a extensão ".txt". Em seguida, usamos um loop foreach para percorrer os arquivos retornados pelo iterador GetArquivosComExtensao e imprimi-los no console.
Esse exemplo demonstra como usar o "yield" para lidar com a iteração sobre uma grande quantidade de arquivos em um diretório, retornando apenas os arquivos desejados conforme necessário, em vez de carregar todos eles na memória de uma vez.
A seguir temos as vantagens e desvantagens do yield:
Vantagens:
Desvantagens:
E estamos conversados.
"Deus nos ressuscitou com Cristo e com ele nos fez
assentar nos lugares celestiais em Cristo Jesus, para mostrar, nas eras que hão
de vir, a incomparável riqueza de sua graça, demonstrada em sua bondade para
conosco em Cristo Jesus. "
Efésios 2:6-7
Referências: