quinta-feira, 1 de outubro de 2009

C# - Yield return

Olá, amigos! Hoje falarei sobre uma funcionalidade interessante do C#.

Existem algumas funcionalidades simples que poupam um trabalhão mas nem sempre são usadas. Como uma dessas funcionalidades, podemos considerar o iterador "yield".

Esta funcionalidade está disponível desde a versão 2.0 do C# mas acaba passando despercebida pela maioria dos desenvolvedores.
Basicamente, o operador "yield" é usado para iterar através de objetos retornados por um método. Ele cria um mecanismo de estado via IL para que seja possível criar métodos que conservem o seu estado sem ser necessário manter o estado via código.

Como exemplo simples, vamos usar um exemplo simples que retorna os itens pares em uma coleção:

public IEnumerable RetornaPares(int[] numeros)
{
    List<int> pares = new List<int>();
    foreach (int n in numeros)
    {
        if (n % 2 == 0)
            pares.Add(n);
    }
    return pares;
}

Normalmente usamos um list para armazenar os itens a serem retornados.
Usando yield return ficaria assim:

public IEnumerable PegarPares(int[] numeros)
{
    foreach (int n in numeros)
    {
        if (n % 2 == 0)
            yield return n;
    }
}

Veja que o yield faz o trabalho para você e retorna o resultado correto, porém iterando pelos itens sem a intervenção do desenvolvedor, não sendo necessário criar nenhuma lista para o armazenamento.

Até a próxima!

Referências:

http://www.c-sharpcorner.com/UploadFile/rmcochran/yieldreturn04022006113850AM/yieldreturn.aspx

http://www.magodigital.info/post/Operador-Yield-do-C.aspx

5 comentários:

Kelps Leite de Sousa disse...

Muito boa a explicação, mas você esqueceu de mencionar um dos principais motivos para utilizar o yield (além de simplificar o código), que é para economizar recursos. Por exemplo: Você executa um looping em um DataReader e a cada volta cria um objeto novo a partir do banco de dados e o retorna usando o yield. Se o código que está utilizando a sua função para obter a enumeração de valores decidir sair do looping (por exemplo, se estiver paginando dados e tiver obtido todos os dados da página atual), você não terá que ler o DataReader até o final como teria que ter feito se não utilizasse o yield, ganhando com isso tempo e economizando memória.

Parabéns pelo post. Muito bem escrito e claro.

Isac disse...

Post muito legal e esclarecedor

Consegui clarear a funcionalidade do yield melhor.

Valeu cara.

Felipe Almeida disse...
Este comentário foi removido pelo autor.
Felipe Almeida disse...

o que o Kelps disse é verdade, um dos principais motivos para se utilizar o Yield Return é devido a sua performance em alguns casos...
Criei um post com a comparação em termos de processamento e memória utilizando o yield return, ficou bem interessante:
http://economizandobits.blogspot.com.br/2013/02/yield-return.html

Alexandre Nascimento disse...

Kelps, Felipe e Isac, muito obrigado pelos comentários e observações!