rendimento (referência de C#)
Quando você usa a palavra-chave yield em uma declaração, você indica que o método, o operador, ou o acessador de get em que aparece são um iterador.Você usa um iterador para executar uma iteração personalizado em uma coleção.O exemplo a seguir mostra os dois formulários de instrução de yield .
yield return <expression>;
yield break;
Comentários
Você usa uma instrução de yield return para retornar um de cada vez a cada elemento.
Você consome um método de iterador usando uma instrução de foreach ou a consulta LINQ.Cada iteração do loop de foreach chama o método de iterador.Quando uma declaração de yield return é alcançada no método de iterador, expression é retornado, e o local atual no código é mantido.A execução é reiniciada de aquele local na próxima vez que a função de iterador é chamada.
Você pode usar uma instrução de yield break para finalizar a iteração.
Para obter mais informações sobre iteradores, consulte Iteradores (C# e Visual Basic).
Os métodos de acessadores get e iterador
A declaração de um iterador deve atender aos seguintes requisitos:
O tipo de retorno deve ser IEnumerable, IEnumerable<T>, IEnumerator, ou IEnumerator<T>.
A declaração não pode ter quaisquer parâmetros de referência ou de para fora .
Uma conversão implícita deve existir do tipo de expressão na declaração de yield return para o tipo de retorno de iterador.
Você não pode incluir uma declaração de yield return ou de yield break em métodos que têm as seguintes características:
Métodos anônimos.Para obter mais informações, consulte Métodos anônimos (guia de programação do C#).
Métodos que contêm blocos não seguro.Para obter mais informações, consulte não seguros (C# Reference).
Manipulação de exceção
Uma declaração de yield return não pode ser localizado em um bloco try-catch.Uma declaração de yield return pode estar localizada no bloco try de uma instrução try - final.
Uma declaração de yield break pode ser localizado em um bloco try ou em um bloco catch mas não em um bloco finally.
Se o corpo de foreach (fora do método de iterador) gera uma exceção, um bloco de finally no método de iterador é executado.
Implementação técnica
O código a seguir retorna IEnumerable<string> de um método de iterador e iterar-lo em através de seus elementos.
IEnumerable<string> elements = MyIteratorMethod();
foreach (string element in elements)
{
…
}
A chamada a MyIteratorMethod não executa o corpo do método.Em vez de chamada retorna IEnumerable<string> na variável de elements .
Em uma iteração do loop de foreach , o método de MoveNext é chamado para elements.Esta chamada executa o corpo de MyIteratorMethod até que a próxima instrução de yield return seja alcançado.A expressão retornada pela instrução de yield return não apenas determina o valor da variável de element consumíveis pelo corpo de loop mas também da propriedade de Current de elementos, que é IEnumerable<string>.
Em cada iteração subsequente do loop de foreach , a execução do corpo de iterador continua de onde parou novamente, parando quando atinge uma instrução de yield return .O loop de foreach termina quando o final do método de iterador ou uma declaração de yield break é alcançado.
Exemplo
O exemplo a seguir tem uma instrução de yield return que está dentro de um loop de for .Cada iteração do corpo de instrução de foreach em Process cria uma chamada para a função de iterador de Power .Cada chamada à função de iterador continua a seguir execução da declaração de yield return , que ocorre durante a próxima iteração do loop de for .
O tipo de retorno do método de iterador é IEnumerable, que é um tipo de interface de iterador.Quando o método de iterador é chamado, retorna um objeto enumerável que contém a potências de um número.
public class PowersOf2
{
static void Main()
{
// Display powers of 2 up to the exponent of 8:
foreach (int i in Power(2, 8))
{
Console.Write("{0} ", i);
}
}
public static System.Collections.IEnumerable Power(int number, int exponent)
{
int result = 1;
for (int i = 0; i < exponent; i++)
{
result = result * number;
yield return result;
}
}
// Output: 2 4 8 16 32 64 128 256
}
O exemplo a seguir demonstra um acessador de get que é um iterador.No exemplo, cada declaração de yield return retorna uma instância de uma classe definida pelo usuário.
public static class GalaxyClass
{
public static void ShowGalaxies()
{
var theGalaxies = new Galaxies();
foreach (Galaxy theGalaxy in theGalaxies.NextGalaxy)
{
Debug.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears.ToString());
}
}
public class Galaxies
{
public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy
{
get
{
yield return new Galaxy { Name = "Tadpole", MegaLightYears = 400 };
yield return new Galaxy { Name = "Pinwheel", MegaLightYears = 25 };
yield return new Galaxy { Name = "Milky Way", MegaLightYears = 0 };
yield return new Galaxy { Name = "Andromeda", MegaLightYears = 3 };
}
}
}
public class Galaxy
{
public String Name { get; set; }
public int MegaLightYears { get; set; }
}
}
Especificação da linguagem C#
Para obter mais informações, consulte Especificação de linguagem do C# A especificação da linguagem é a fonte definitiva para a sintaxe e o uso da linguagem C#.