foreach, in (Referencia de C#)foreach, in (C# reference)

La instrucción foreach ejecuta una instrucción o un bloque de instrucciones para cada elemento en una instancia del tipo que implementa la interfaz System.Collections.IEnumerable o System.Collections.Generic.IEnumerable<T>.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. La instrucción foreach no se limita a esos tipos y puede aplicarse a una instancia de cualquier tipo que cumpla las siguientes condiciones:The foreach statement isn't limited to those types and can be applied to an instance of any type that satisfies the following conditions:

  • tiene el método público sin parámetros GetEnumerator cuyo tipo de valor devuelto es clase, estructura o tipo de interfaz,has the public parameterless GetEnumerator method whose return type is either class, struct, or interface type,
  • el tipo de valor devuelto del método GetEnumerator tiene la propiedad pública Current y el método público sin parámetros MoveNext cuyo tipo de valor devuelto es Boolean.the return type of the GetEnumerator method has the public Current property and the public parameterless MoveNext method whose return type is Boolean.

En la mayoría de casos, foreach itera una expresión IEnumerable<T> en la que cada elemento es de tipo T.In most uses, foreach iterates an IEnumerable<T> expression where each element is of type T. Pero los elementos pueden ser de cualquier tipo que tenga una conversión implícita o explícita del tipo de la propiedad Current.However, the elements may be any type that has an implicit or explicit conversion from the type of the Current property. Si la propiedad Current devuelve SomeType, el tipo de los elementos puede ser uno de los siguientes:If the Current property returns SomeType, the type of the elements may be:

  • Cualquiera de las clases base de SomeType.Any of the base classes of SomeType.
  • Cualquiera de las interfaces implementadas por SomeType.Any of the interfaces implemented by SomeType.

Además, si SomeType es una class o una interface y no tiene el estado sealed, el tipo de elemento puede ser uno de los siguientes:Furthermore, if SomeType is a class or an interface and not sealed, the type of elements may include:

  • Cualquier tipo derivado de SomeType.Any type derived from SomeType.
  • Cualquier interfaz arbitraria.Any arbitrary interface. Se permite cualquier interfaz porque se puede usar una clase derivada de SomeType o que implemente este elemento para implementar cualquier interfaz.Any interface is allowed because any interface may be implemented by a class derived from or implementing SomeType.

Puede declarar la variable de iteración con cualquier tipo que coincida con las reglas anteriores.You may declare the iteration variable using any type that matches the preceding rules. Si la conversión de SomeType al tipo de la variable de iteración requiere una conversión explícita, dicha operación puede producir una excepción InvalidCastException al producirse un error de conversión.If the conversion from SomeType to the type of the iteration variable requires an explicit cast, that operation may throw an InvalidCastException when the conversion fails.

A partir de C# 7.3, si la propiedad Current del enumerador devuelve un valor devuelto de referencia (ref T donde T es el tipo del elemento de colección), se puede declarar la variable de iteración con el modificador ref o ref readonly.Beginning with C# 7.3, if the enumerator's Current property returns a reference return value (ref T where T is the type of the collection element), you can declare the iteration variable with the ref or ref readonly modifier.

A partir de C# 8.0, el operador await se puede aplicar a la instrucción foreach cuando el tipo de colección implemente la interfaz IAsyncEnumerable<T>.Beginning with C# 8.0, the await operator may be applied to the foreach statement when the collection type implements the IAsyncEnumerable<T> interface. Cada iteración del bucle se puede suspender mientras el siguiente elemento se recupera de forma asincrónica.Each iteration of the loop may be suspended while the next element is retrieved asynchronously. Los elementos de secuencia se procesan de forma predeterminada en el contexto capturado.By default, stream elements are processed in the captured context. Si quiere deshabilitar la captura del contexto, use el método de extensión TaskAsyncEnumerableExtensions.ConfigureAwait.If you want to disable capturing of the context, use the TaskAsyncEnumerableExtensions.ConfigureAwait extension method. Para obtener más información sobre los contextos de sincronización y la captura del contexto actual, vea el artículo sobre el consumo del patrón asincrónico basado en tareas.For more information about synchronization contexts and capturing the current context, see the article on consuming the Task-based asynchronous pattern.

En cualquier punto del bloque de instrucciones foreach, se puede salir del bucle mediante la instrucción break, o bien se puede ir a la siguiente iteración del bucle mediante la instrucción 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. También se puede salir de un bucle foreach mediante las instrucciones goto, return o throw.You can also exit a foreach loop by the goto, return, or throw statements.

Si la instrucción foreach se aplica a null, se produce NullReferenceException.If the foreach statement is applied to null, a NullReferenceException is thrown. Si la colección de origen de la instrucción foreach está vacía, el cuerpo del bucle foreach no se ejecuta y se omite.If the source collection of the foreach statement is empty, the body of the foreach loop isn't executed and skipped.

EjemplosExamples

Nota

Los ejemplos de C# de este artículo se ejecutan en el ejecutor de código en línea y área de juegos de Try.NET.The C# examples in this article run in the Try.NET inline code runner and playground. Haga clic en el botón Ejecutar para ejecutar un ejemplo en una ventana interactiva.Select the Run button to run an example in an interactive window. Una vez que se ejecuta el código, puede modificar y ejecutar el código modificado si vuelve a hacer clic en Ejecutar.Once you execute the code, you can modify it and run the modified code by selecting Run again. El código modificado se ejecuta en la ventana interactiva o, si se produce un error en la compilación, en la ventana interactiva se muestran todos los mensajes de error del compilador de C#.The modified code either runs in the interactive window or, if compilation fails, the interactive window displays all C# compiler error messages.

El siguiente ejemplo muestra el uso de la instrucción foreach con una instancia del tipo List<T> que implementa la interfaz IEnumerable<T>:The following example shows usage of the foreach statement with an instance of the List<T> type that implements the IEnumerable<T> interface:

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}");

El siguiente ejemplo utiliza la instrucción foreach con una instancia del tipo System.Span<T>, que no implementa ninguna interfaz:The next 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();
    }
}

En el ejemplo siguiente se usa una variable de iteración ref para establecer el valor de cada elemento de una matriz stackalloc.The following example uses a ref iteration variable to set the value of each item in a stackalloc array. La versión ref readonly recorre en iteración la colección para imprimir todos los valores.The ref readonly version iterates the collection to print all the values. En la declaración de readonly, se usa una declaración de variable local implícita.The readonly declaration uses an implicit local variable declaration. Las declaraciones de variables implícitas se pueden usar con las declaraciones ref o ref readonly, al igual que las declaraciones de variables con tipo explícito.Implicit variable declarations can be used with either ref or ref readonly declarations, as can explicitly typed variable declarations.

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
    }
}

En el siguiente ejemplo se usa await foreach para iterar por una colección que genera cada elemento de forma asincrónica:The following example uses await foreach to iterate a collection that generates each element asynchronously:

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

Especificación del lenguaje C#C# language specification

Para más información, vea la sección sobre la instrucción foreach de la Especificación del lenguaje C#.For more information, see The foreach statement section of the C# language specification.

Vea tambiénSee also