Neste artigo vou apresentar os conceitos relacionados com a palavra reservada yield da linguagem C#. |
Consultando a referência da linguagem C# temos que :
"Quando você usa a palavra-chave yield em uma instrução, você indica que o método, o operador ou o acessador get em que ela é exibida é um iterador. Usar yield para definir um iterador elimina a necessidade de uma classe adicional explícita (a classe que mantém o estado de uma enumeração, consulte IEnumerator<T> para obter um exemplo) ao implementar o padrão IEnumerable e IEnumerator para um tipo de coleção personalizado."
O exemplo a seguir mostra as duas formas de instrução yield.
yield return <expression>;
yield break;
- Você usa
uma instrução yield return para retornar cada elemento
individualmente.
- Você pode usar uma instrução yield break para terminar a iteração.
Você não pode incluir uma instrução yield return ou yield break nos métodos com as seguintes características:
Métodos anônimos
Métodos que contêm blocos inseguros
Verifique as seguintes restrições quanto ao tratamento de exceções usando yield:
Da teoria à prática
Em geral, usamos a palavra reservada yield em métodos que retornam o tipo IEnumerable ou IEnumerable<T>.
Vejamos um exemplo bem simples: (adaptado do site: yield (Referência de C#) - MSDN - Microsoft )
No código à direita estamos usando a palavra reservada yield para retornar o valor do método Potencia() que é do tipo IEnumerable.
No código à esquerda removemos o yield e obtemos duas exceções conforme mostra a imagem:
using System;
using System.Collections.Generic;
namespace Cshp_yield
{
class Program
{
static void Main(string[] args)
{
// Exibe a potência de 2 elevado ao expoente 8
foreach (int i in Potencia(2, 8))
{
Console.Write("{0} ", i);
}
Console.ReadKey();
}
public static IEnumerable<int> Potencia(int numero, int exponente)
{
int resultado = 1;
for (int i = 0; i < exponente; i++)
{
resultado = resultado * numero;
yield return resultado;
}
}
}
}
|
|
No código
temos uma instrução yield return dentro de um loop foreach
onde cada iteração do corpo da instrução cria uma chamada ao método
Potencia.
Cada chamada ao método prossegue para a próxima execução da instrução
yield return que ocorre durante a próxima iteração do loop foreach.
O tipo de retorno do método iterador é IEnumerable que é um tipo de
interface de iterador. Quando o método iterador é chamado, ele retorna um
objeto enumerável que contém as potências de um número.
Podemos então usar o yield para gerar um Enumerable de qualquer coisa como por exemplo gerar um coleção de números inteiros:
class Program
{
static void Main(string[] args)
{
var numeros = Numeros(0, 10);
foreach(int num in numeros)
{
Console.WriteLine(num);
}
Console.ReadKey();
}
public static IEnumerable<int> Numeros(int inicio, int fim)
{
for (int i = inicio; i <= fim; i++)
yield return i;
}
}
|
|
Ou retornar um Enumerable de strings :
class Program
{
static void Main(string[] args)
{
var palavras = ConverteParaCaixaBaixa("Macoratti .net, quase tudo para .Net");
foreach (string pal in palavras)
{
Console.Write("{0} ", pal) ;
}
}
public static IEnumerable<string> ConverteParaCaixaBaixa(string frase)
{
foreach (var palavra in frase.Split(' '))
{
yield return palavra.ToLower();
}
}
}
|
|
Assim, creio que você já sacou para que serve e como deve usar o yield.
E estamos conversados...
"Se alguém me serve, siga-me, e onde
eu estiver, ali estará também o meu servo. E, se alguém me servir, meu Pai o
honrará. "
João 12:26
Referências:
Visual Studio - Dica de produtividade - Quick Launch - Macoratti.net
Visual Studio - Dica de produtividade - Nuget - Macoratti.net