Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Instrucciones de iteración:
Las instrucciones de iteración ejecutan repetidamente una instrucción o un bloque de instrucciones. La instrucción for
ejecuta su cuerpo mientras una expresión booleana especificada se evalúa como true
. La instrucción foreach
enumera los elementos de una colección y ejecuta su cuerpo para cada elemento de la colección. La instrucción do
ejecuta condicionalmente su cuerpo una o varias veces. La instrucción while
ejecuta condicionalmente su cuerpo cero o varias veces.
En cualquier punto del cuerpo de una instrucción de iteración, se puede salir del bucle mediante la instrucción break
. Puede avanzar a la siguiente iteración en el bucle utilizando la continue
sentencia.
Instrucción for
La for
instrucción ejecuta una instrucción o un bloque de instrucciones mientras una expresión booleana especificada se evalúa como true
. En el ejemplo siguiente se muestra la instrucción for
, que ejecuta su cuerpo mientras que un contador entero sea menor que tres:
for (int i = 0; i < 3; i++)
{
Console.Write(i);
}
// Output:
// 012
En el ejemplo anterior se muestran los elementos de la for
declaración.
La sección de inicializador que se ejecuta solo una vez, antes de entrar en el bucle. Normalmente, se declara e inicializa una variable de bucle local en esa sección. No se puede tener acceso a la variable declarada desde fuera de la
for
instrucción .La sección initializer del ejemplo anterior declara e inicializa una variable de contador entero:
int i = 0
Sección de condición que determina si se debe ejecutar la siguiente iteración del bucle. Si se evalúa como
true
o no está presente, se ejecuta la siguiente iteración; de lo contrario, se sale del bucle. La sección condition debe ser una expresión booleana.La sección condition del ejemplo anterior comprueba si un valor de contador es menor que tres:
i < 3
Sección iterador que define lo que sucede después de cada ejecución del cuerpo del bucle.
La sección iterador del ejemplo anterior incrementa el contador:
i++
El cuerpo del bucle, que es una instrucción o un bloque de instrucciones.
La sección iterador puede contener cero o más de las siguientes expresiones de instrucción, separadas por comas:
- expresión de incremento de prefijo o sufijo, como
++i
oi++
- expresión de decremento de prefijo o sufijo, como
--i
oi--
- asignación
- invocación de un método
-
await
Expresión - creación de un objeto mediante el
new
operador
Si no declara una variable de bucle en la sección de inicializador, puede usar cero o más de las expresiones de la lista anterior también en la sección de inicializador. En el ejemplo siguiente se muestran varios usos menos comunes de las secciones de inicializador e iterador: asignar un valor a una variable externa en la sección inicializador, invocar un método en las secciones inicializador y iterador, y cambiar los valores de dos variables en la sección iterador:
int i;
int j = 3;
for (i = 0, Console.WriteLine($"Start: i={i}, j={j}"); i < j; i++, j--, Console.WriteLine($"Step: i={i}, j={j}"))
{
//...
}
// Output:
// Start: i=0, j=3
// Step: i=1, j=2
// Step: i=2, j=1
Todas las secciones de la for
instrucción son opcionales. Por ejemplo, el código siguiente define el bucle infinito for
:
for ( ; ; )
{
//...
}
Instrucción foreach
La foreach
instrucción ejecuta una instrucción o un bloque de instrucciones para cada elemento de una instancia del tipo que implementa la System.Collections.IEnumerable interfaz o System.Collections.Generic.IEnumerable<T> , como se muestra en el ejemplo siguiente:
List<int> fibNumbers = new() { 0, 1, 1, 2, 3, 5, 8, 13 };
foreach (int element in fibNumbers)
{
Console.Write($"{element} ");
}
// Output:
// 0 1 1 2 3 5 8 13
La foreach
declaración no se limita a esos tipos. Puede usarlo con una instancia de cualquier tipo que cumpla las condiciones siguientes:
- Un tipo tiene el método público
GetEnumerator
sin parámetros. ElGetEnumerator
método puede ser el método de extensión de un tipo. - El tipo de valor devuelto del
GetEnumerator
método tiene la propiedad públicaCurrent
y el método público sinMoveNext
parámetros cuyo tipo de valor devuelto esbool
.
En el ejemplo siguiente se usa la instrucción foreach
con una instancia del tipo System.Span<T>, que no implementa ninguna interfaz.
Span<int> numbers = [3, 14, 15, 92, 6];
foreach (int number in numbers)
{
Console.Write($"{number} ");
}
// Output:
// 3 14 15 92 6
Si la propiedad del Current
enumerador devuelve un valor de retorno por referencia (ref T
donde T
es el tipo de un elemento de colección), puede declarar una variable de iteración con el modificador ref
o ref readonly
, como se muestra en el ejemplo siguiente.
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
Si la colección de origen de la foreach
instrucción está vacía, el bloque de la foreach
instrucción no se ejecuta y se omite. Si la foreach
instrucción se aplica a null
, se lanza un objeto NullReferenceException.
await foreach
Puede usar la await foreach
instrucción para consumir un flujo asincrónico de datos, es decir, el tipo de colección que implementa la IAsyncEnumerable<T> interfaz. Cada iteración del bucle se puede suspender mientras el elemento siguiente se recupera de forma asincrónica. En el ejemplo siguiente se muestra cómo usar la await foreach
instrucción :
await foreach (var item in GenerateSequenceAsync())
{
Console.WriteLine(item);
}
También puede usar la await foreach
instrucción con una instancia de cualquier tipo que cumpla las condiciones siguientes:
- Un tipo tiene el método público
GetAsyncEnumerator
sin parámetros. Ese método puede ser el método de extensión de un tipo. - El tipo de valor devuelto del método
GetAsyncEnumerator
tiene la propiedad públicaCurrent
y el método públicoMoveNextAsync
sin parámetros cuyo tipo de valor devuelto esTask<bool>
,ValueTask<bool>
, o cualquier otro tipo que se puede esperar cuyo métodoGetResult
de awaiter devuelve un valorbool
.
De forma predeterminada, los elementos de secuencia se procesan en el contexto capturado. Si desea deshabilitar la captura del contexto, use el TaskAsyncEnumerableExtensions.ConfigureAwait método de extensión . Para obtener más información sobre los contextos de sincronización y la captura del contexto actual, consulte Consumo del patrón asincrónico basado en tareas. Para obtener más información sobre las secuencias asincrónicas, consulte el tutorial Secuencias asincrónicas.
Tipo de una variable de iteración
Puede usar la var
palabra clave para permitir que el compilador infiera el tipo de una variable de iteración en la foreach
instrucción , como se muestra en el código siguiente:
foreach (var item in collection) { }
Nota:
El compilador puede inferir el tipo de var
como un tipo de referencia anulable, dependiendo de si el contexto de referencia nulable está habilitado y si el tipo de la expresión de inicialización es un tipo de referencia.
Para obtener más información, consulte Variables locales con tipo implícito.
También puede especificar explícitamente el tipo de una variable de iteración, como se muestra en el código siguiente:
IEnumerable<T> collection = new T[5];
foreach (V item in collection) { }
En el formato anterior, el tipo T
de un elemento de colección debe convertirse implícita o explícitamente en el tipo V
de una variable de iteración. Si una conversión explícita de T
a V
falla en tiempo de ejecución, la instrucción foreach
lanza una InvalidCastException. Por ejemplo, si T
es un tipo de clase no sellado, V
puede ser cualquier tipo de interfaz, incluso el que T
no implementa. En tiempo de ejecución, el tipo de un elemento de colección puede ser el que deriva de T
y realmente implementa V
. Si ese no es el caso, se produce InvalidCastException.
Instrucción do
La do
instrucción ejecuta una instrucción o un bloque de instrucciones mientras una expresión booleana especificada se evalúa como true
. Dado que esa expresión se evalúa después de cada ejecución del bucle, un do
bucle se ejecuta una o varias veces. El do
bucle difiere del while
bucle , que ejecuta cero o más veces.
En el ejemplo siguiente se muestra el uso de la declaración do
:
int n = 0;
do
{
Console.Write(n);
n++;
} while (n < 5);
// Output:
// 01234
Instrucción while
La while
instrucción ejecuta una instrucción o un bloque de instrucciones mientras una expresión booleana especificada se evalúa como true
. Dado que esa expresión se evalúa antes de cada ejecución del bucle, un while
bucle ejecuta cero o más veces. El while
bucle difiere del do
bucle , que se ejecuta una o varias veces.
En el ejemplo siguiente se muestra el uso de la declaración while
:
int n = 0;
while (n < 5)
{
Console.Write(n);
n++;
}
// Output:
// 01234
Especificación del lenguaje C#
Para más información, vea las secciones siguientes de la Especificación del lenguaje C#:
Para obtener más información sobre estas características, consulte las siguientes notas de propuesta de características: