yield (Referência de C#)yield (C# Reference)

Ao usar a palavra-chave contextual yield em uma instrução, você indica que o método, o operador ou o acessador get em que ela é exibida é um iterador.When you use the yield contextual keyword in a statement, you indicate that the method, operator, or get accessor in which it appears is an iterator. 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.Using yield to define an iterator removes the need for an explicit extra class (the class that holds the state for an enumeration, see IEnumerator<T> for an example) when you implement the IEnumerable and IEnumerator pattern for a custom collection type.

O exemplo a seguir mostra as duas formas de instrução yield.The following example shows the two forms of the yield statement.

yield return <expression>;  
yield break;  

ComentáriosRemarks

Você usa uma instrução yield return para retornar cada elemento individualmente.You use a yield return statement to return each element one at a time.

Você consome um método iterador ao usar uma instrução foreach ou consulta LINQ.You consume an iterator method by using a foreach statement or LINQ query. Cada iteração do loop foreach chama o método iterador.Each iteration of the foreach loop calls the iterator method. Quando uma instrução yield return é atingida no método iterador, expression é retornado e o local atual no código é retido.When a yield return statement is reached in the iterator method, expression is returned, and the current location in code is retained. A execução será reiniciada desse local na próxima vez que a função iteradora for chamada.Execution is restarted from that location the next time that the iterator function is called.

Você pode usar uma instrução yield break para terminar a iteração.You can use a yield break statement to end the iteration.

Para obter mais informações sobre iteradores, consulte Iteradores.For more information about iterators, see Iterators.

Métodos de Iterador Acessadores getIterator Methods and get Accessors

A declaração de um iterador deve atender aos seguintes requisitos:The declaration of an iterator must meet the following requirements:

O tipo yield de um iterador que retorna IEnumerable ou IEnumerator é object.The yield type of an iterator that returns IEnumerable or IEnumerator is object. Se o iterador retornar IEnumerable<T> ou IEnumerator<T>, uma conversão implícita deverá existir do tipo da expressão na instrução yield return para o parâmetro de tipo genérico.If the iterator returns IEnumerable<T> or IEnumerator<T>, there must be an implicit conversion from the type of the expression in the yield return statement to the generic type parameter .

Você não pode incluir uma instrução yield return ou yield break nos métodos com as seguintes características:You can't include a yield return or yield break statement in methods that have the following characteristics:

  • Métodos anônimos.Anonymous methods. Para obter mais informações, consulte Métodos anônimos.For more information, see Anonymous Methods.

  • Métodos que contêm blocos inseguros.Methods that contain unsafe blocks. Para obter mais informações, consulte unsafe.For more information, see unsafe.

Tratamento de ExceçãoException Handling

Uma instrução yield return não pode estar localizada em um bloco try-catch.A yield return statement can't be located in a try-catch block. Uma instrução yield return pode estar localizada no bloco try de uma instrução try-finally.A yield return statement can be located in the try block of a try-finally statement.

Uma instrução yield break pode estar localizada em um bloco try ou em um bloco catch, mas não em um bloco finally.A yield break statement can be located in a try block or a catch block but not a finally block.

Se o corpo foreach (fora do método iterador) acionar uma exceção, um bloco finally no método iterador será executado.If the foreach body (outside of the iterator method) throws an exception, a finally block in the iterator method is executed.

Implementação TécnicaTechnical Implementation

O código a seguir retorna uma IEnumerable<string> de um método iterador e itera através de seus elementos.The following code returns an IEnumerable<string> from an iterator method and then iterates through its elements.

IEnumerable<string> elements = MyIteratorMethod();  
foreach (string element in elements)  
{  
   ...  
}  

A chamada a MyIteratorMethod não executa o corpo do método.The call to MyIteratorMethod doesn't execute the body of the method. Em vez disso, a chamada retorna IEnumerable<string> na variável elements.Instead the call returns an IEnumerable<string> into the elements variable.

Em uma iteração do loop foreach, o método MoveNext é chamado para elements.On an iteration of the foreach loop, the MoveNext method is called for elements. Essa chamada executará o corpo de MyIteratorMethod até que a próxima instrução yield return seja atingida.This call executes the body of MyIteratorMethod until the next yield return statement is reached. A expressão retornada pela instrução yield return determina não apenas o valor da variável element para o consumo do corpo do loop, mas também a propriedade Current de elements, que é uma IEnumerable<string>.The expression returned by the yield return statement determines not only the value of the element variable for consumption by the loop body but also the Current property of elements, which is an IEnumerable<string>.

Em cada iteração subsequente do loop foreach, a execução do corpo do iterador continuará de onde parou, parando novamente quando atingir uma instrução yield return.On each subsequent iteration of the foreach loop, the execution of the iterator body continues from where it left off, again stopping when it reaches a yield return statement. O loop foreach é concluído quando o fim do método iterador ou uma instrução yield break é atingida.The foreach loop completes when the end of the iterator method or a yield break statement is reached.

ExemploExample

O exemplo a seguir contém uma instrução yield return dentro de um loop for.The following example has a yield return statement that's inside a for loop. Cada iteração do corpo da instrução foreach no método Main cria uma chamada à função iteradora Power.Each iteration of the foreach statement body in the Main method creates a call to the Power iterator function. Cada chamada à função iteradora prossegue para a próxima execução da instrução yield return que ocorre durante a próxima iteração do loop for.Each call to the iterator function proceeds to the next execution of the yield return statement, which occurs during the next iteration of the for loop.

O tipo de retorno do método iterador é IEnumerable que é um tipo de interface de iterador.The return type of the iterator method is IEnumerable, which is an iterator interface type. Quando o método iterador é chamado, ele retorna um objeto enumerável que contém as potências de um número.When the iterator method is called, it returns an enumerable object that contains the powers of a number.

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.Generic.IEnumerable<int> 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
}

ExemploExample

O exemplo a seguir demonstra um acessador get que é um iterador.The following example demonstrates a get accessor that is an iterator. No exemplo, cada instrução yield return retorna uma instância de uma classe definida pelo usuário.In the example, each yield return statement returns an instance of a user-defined class.

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#C# Language Specification

Para obter mais informações, consulte a Especificação da linguagem C#.For more information, see the C# Language Specification. A especificação da linguagem é a fonte definitiva para a sintaxe e o uso de C#.The language specification is the definitive source for C# syntax and usage.

Consulte tambémSee Also