foreach, in (Referência em C#)foreach, in (C# reference)

A foreach instrução executa uma instrução ou um bloco de instruções para cada elemento em uma instância do tipo que implementa a System.Collections.IEnumerable System.Collections.Generic.IEnumerable<T> interface ou, como mostra o exemplo a seguir:The foreach statement executes a statement or a block of statements for each element in an instance of the type that implements the System.Collections.IEnumerable or System.Collections.Generic.IEnumerable<T> interface, as the following example shows:

var fibNumbers = new List<int> { 0, 1, 1, 2, 3, 5, 8, 13 };
int count = 0;
foreach (int element in fibNumbers)
{
    count++;
    Console.WriteLine($"Element #{count}: {element}");
}
Console.WriteLine($"Number of elements: {count}");

A foreach instrução não está limitada a esses tipos.The foreach statement isn't limited to those types. Você pode usá-lo com uma instância de qualquer tipo que atenda às seguintes condições:You can use it with an instance of any type that satisfies the following conditions:

  • Um tipo tem o método público sem parâmetros GetEnumerator cujo tipo de retorno é Class, struct ou interface Type.A type has the public parameterless GetEnumerator method whose return type is either class, struct, or interface type. A partir do C# 9,0, o GetEnumerator método pode ser o método de extensãode um tipo.Beginning with C# 9.0, the GetEnumerator method can be a type's extension method.
  • O tipo de retorno do GetEnumerator método tem a Current propriedade Public e o método público sem parâmetros MoveNext cujo tipo de retorno é Boolean .The return type of the GetEnumerator method has the public Current property and the public parameterless MoveNext method whose return type is Boolean.

O exemplo a seguir usa a foreach instrução com uma instância do System.Span<T> tipo, que não implementa nenhuma interface:The following example uses the foreach statement with an instance of the System.Span<T> type, which doesn't implement any interfaces:

public class IterateSpanExample
{
    public static void Main()
    {
        Span<int> numbers = new int[] { 3, 14, 15, 92, 6 };
        foreach (int number in numbers)
        {
            Console.Write($"{number} ");
        }
        Console.WriteLine();
    }
}

A partir do C# 7,3, se a propriedade do enumerador Current retornar um valor de retorno de referência ( ref T em que T é o tipo de um elemento de coleção), você poderá declarar uma variável de iteração com o ref ref readonly modificador ou, como mostra o exemplo a seguir:Beginning with C# 7.3, if the enumerator's Current property returns a reference return value (ref T where T is the type of a collection element), you can declare an iteration variable with the ref or ref readonly modifier, as the following example shows:

public class ForeachRefExample
{
    public static void Main()
    {
        Span<int> storage = stackalloc int[10];
        int num = 0;
        foreach (ref int item in storage)
        {
            item = num++;
        }

        foreach (ref readonly var item in storage)
        {
            Console.Write($"{item} ");
        }
        // Output:
        // 0 1 2 3 4 5 6 7 8 9
    }
}

A partir do C# 8,0, você pode usar a await foreach instrução para consumir um fluxo de dados assíncrono, ou seja, o tipo de coleção que implementa a IAsyncEnumerable<T> interface.Beginning with C# 8.0, you can use the await foreach statement to consume an asynchronous stream of data, that is, the collection type that implements the IAsyncEnumerable<T> interface. Cada iteração do loop pode ser suspensa enquanto o próximo elemento é recuperado de forma assíncrona.Each iteration of the loop may be suspended while the next element is retrieved asynchronously. O exemplo a seguir mostra como usar a await foreach instrução:The following example shows how to use the await foreach statement:

await foreach (var item in GenerateSequenceAsync())
{
    Console.WriteLine(item);
}

Por padrão, os elementos de fluxo são processados no contexto capturado.By default, stream elements are processed in the captured context. Se você quiser desabilitar a captura do contexto, use o TaskAsyncEnumerableExtensions.ConfigureAwait método de extensão.If you want to disable capturing of the context, use the TaskAsyncEnumerableExtensions.ConfigureAwait extension method. Para obter mais informações sobre contextos de sincronização e como capturar o contexto atual, consulte consumindo o padrão assíncrono baseado em tarefa.For more information about synchronization contexts and capturing the current context, see Consuming the Task-based asynchronous pattern. Para obter mais informações sobre fluxos assíncronos, consulte a seção fluxos assíncronos do artigo novidades no C# 8,0 .For more information about asynchronous streams, see the Asynchronous streams section of the What's new in C# 8.0 article.

Em qualquer ponto dentro do bloco de instrução foreach, você pode sair do loop usando a instrução break ou seguir para a próxima iteração no loop usando a instrução continue.At any point within the foreach statement block, you can break out of the loop by using the break statement, or step to the next iteration in the loop by using the continue statement. Você também pode sair de um foreach loop pelas instruções goto, Returnou throw .You can also exit a foreach loop by the goto, return, or throw statements.

Se a instrução foreach for aplicada a null, uma NullReferenceException será gerada.If the foreach statement is applied to null, a NullReferenceException is thrown. Se a coleção de origem da foreach instrução estiver vazia, o corpo do foreach loop não será executado e ignorado.If the source collection of the foreach statement is empty, the body of the foreach loop isn't executed and skipped.

Tipo de uma variável de iteraçãoType of an iteration variable

Você pode usar a var palavra-chave para permitir que o compilador inferir o tipo de uma variável de iteração na foreach instrução, como mostra o código a seguir:You can use the var keyword to let the compiler infer the type of an iteration variable in the foreach statement, as the following code shows:

foreach (var item in collection) { }

Você também pode especificar explicitamente o tipo de uma variável de iteração, como mostra o código a seguir:You can also explicitly specify the type of an iteration variable, as the following code shows:

IEnumerable<T> collection = new T[5];
foreach (V item in collection) { }

No formulário anterior, o tipo T de um elemento de coleção deve ser implicitamente ou explicitamente conversível para V o tipo de uma variável de iteração.In the preceding form, type T of a collection element must be implicitly or explicitly convertible to type V of an iteration variable. Se uma conversão explícita de T para V falhar em tempo de execução, a foreach instrução lançará um InvalidCastException .If an explicit conversion from T to V fails at run time, the foreach statement throws an InvalidCastException. Por exemplo, se T for um tipo de classe não lacrado, V pode ser qualquer tipo de interface, até mesmo aquele que T não implementa.For example, if T is a non-sealed class type, V can be any interface type, even the one that T doesn't implement. No tempo de execução, o tipo de um elemento de coleção pode ser o que deriva de T e realmente implementa V .At run time, the type of a collection element may be the one that derives from T and actually implements V. Se esse não for o caso, um InvalidCastException será lançado.If that's not the case, an InvalidCastException is thrown.

Especificação da linguagem C#C# language specification

Para obter mais informações, confira a seção A instrução foreach na Especificação da linguagem C#.For more information, see The foreach statement section of the C# language specification.

Para obter mais informações sobre os recursos adicionados em C# 8,0 e posterior, consulte as seguintes notas de proposta de recurso:For more information about features added in C# 8.0 and later, see the following feature proposal notes:

Consulte tambémSee also