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.
Tip
Este artículo forma parte de la sección Aspectos básicos de los desarrolladores que ya conocen al menos un lenguaje de programación y están aprendiendo C#. Si no está familiarizado con la programación, comience primero con los tutoriales de introducción . Para obtener la sintaxis completa, consulte instrucciones de iteración en la referencia del lenguaje.
¿Viene de otro idioma? Los cuatro bucles de C# (foreach, while,do-while y for) tienen equivalentes directos en Java, C++y JavaScript. La mayoría de las veces se usa foreach . Itera sobre una colección sin índice, como for mejorado de Java o for...of de JavaScript.
Las instrucciones de iteración ejecutan un bloque de código repetidamente. Cada paso por el bloque es una iteración y un bloque repetido es un bucle. C# proporciona cuatro bucles. Comience con foreach para colecciones, use while y do-while cuando una condición controle la repetición y use for cuando necesite un índice explícito.
Iteración de una colección con foreach
La foreach instrucción ejecuta su cuerpo una vez para cada elemento de una colección, en orden. Es la opción más común para leer una colección porque no tienes que gestionar un índice ni comprobar los límites. La sentencia foreach evita los errores típicos de desfase de una unidad:
string[] names = ["Ana", "Ben", "Cleo"];
// foreach reads each element in order. It's the default loop for
// collections: no index to manage and no off-by-one mistakes.
foreach (string name in names)
{
Console.WriteLine(name); // => Ana, then Ben, then Cleo
}
foreach funciona con cualquier tipo que C# reconozca como una secuencia, incluidas las matrices, List<T>y Dictionary<TKey,TValue>. La variable de iteración (name en el ejemplo anterior) es de solo lectura, por lo que no se puede reasignar dentro del bucle.
El cuerpo de un bucle es una sola instrucción, como una asignación o una llamada de método. Una instrucción de bloque es en sí misma una sola instrucción que encierra cero o más instrucciones entre llaves ({ }).
Muchos estándares de codificación recomiendan incluir el cuerpo del bucle entre llaves, incluso para una sola instrucción. Las llaves hacen que el ámbito sea explícito. Evita un error común: añadir después una segunda línea que esperas que se ejecute en cada iteración, pero que en cambio se ejecuta una vez después del bucle. Solo las llaves deciden qué instrucciones pertenecen al bucle. C# no considera relevantes los espacios en blanco, por lo que la sangría por sí sola nunca lo es. Las llaves son legales incluso alrededor de una línea: el bloque es la única instrucción que repite el bucle. Sangría del código para mejorar la legibilidad, pero confía en llaves para definir el bloque.
Repetir mientras se cumpla una condición con while
Un while bucle comprueba su condición booleana antes de cada iteración. Si la condición es false al principio, el cuerpo nunca se ejecuta, por lo que un bucle while se ejecuta cero o más veces:
int countdown = 3;
// A while loop checks its condition before each iteration, so the body
// runs zero or more times.
while (countdown > 0)
{
Console.WriteLine(countdown); // => 3, then 2, then 1
countdown--;
}
Asegúrese de que algo dentro del bucle cambie la condición. En el ejemplo anterior, countdown-- finalmente realiza la condición false. Un bucle cuya condición nunca llega a ser false se ejecuta indefinidamente.
Ejecutar al menos una vez el cuerpo con do-while
Un do-while bucle comprueba su condición después de cada iteración, por lo que el cuerpo siempre se ejecuta al menos una vez. Úselo cuando se deba realizar el primer paso antes de poder evaluar la condición, como solicitar la entrada y, a continuación, validarla:
int attempts = 0;
// A do-while loop runs its body once, then checks the condition. Use it
// when the body must run at least one time.
do
{
attempts++;
Console.WriteLine($"Attempt {attempts}"); // => Attempt 1, then Attempt 2, then Attempt 3
}
while (attempts < 3);
Contar con for
Una for instrucción de bucle contiene tres partes: un inicializador que se ejecuta una vez antes del bucle, una condición que se comprueba antes de cada iteración y un iterador que se ejecuta después de cada iteración. Use for cuando necesite el propio índice, no solo los elementos. Normalmente, necesita el índice cuando desee modificar el elemento en lugar de leer su valor.
// A for loop fits when you need an explicit index. The three parts are
// the initializer, the condition, and the iterator.
for (int i = 0; i < 3; i++)
{
Console.WriteLine(i); // => 0, then 1, then 2
}
Cuando solo se leen los elementos, cuando no se usan las posiciones ni se asignan nuevos valores, se prefiere foreach. Indica la intención con más claridad y evita la aritmética de índices.
Salir o omitir con break y continue
Dos instrucciones de salto proporcionan un control más preciso dentro de cualquier bucle. La break instrucción sale del bucle inmediatamente, omitiendo las iteraciones restantes:
int[] numbers = [2, 4, 7, 8];
// break stops the loop immediately, skipping any remaining elements.
foreach (int number in numbers)
{
if (number % 2 != 0)
{
Console.WriteLine($"First odd number: {number}"); // => First odd number: 7
break;
}
}
La continue instrucción omite el resto de la iteración actual y pasa a la siguiente:
int[] values = [1, 2, 3, 4, 5];
// continue skips the rest of the current iteration and moves to the next.
foreach (int value in values)
{
if (value % 2 == 0)
{
continue; // skip even numbers
}
Console.WriteLine(value); // => 1, then 3, then 5
}
Iteración de una secuencia asincrónica con await foreach
Una secuencia asincrónica es un lector que usa una tarea asincrónica para generar cada elemento siguiente. C# lo representa con la IAsyncEnumerable<T> interfaz . Los datos que llegan a lo largo del tiempo, como páginas de una API web o filas de una base de datos, se ajustan a este modelo: recuperar el siguiente elemento es una operación que se puede esperar en lugar de una devolución inmediata.
Para consumir una secuencia asincrónica, coloque la await palabra clave antes de foreach. Cada iteración espera el siguiente elemento, por lo que el bucle se suspende mientras ese elemento se genera en lugar de bloquear el subproceso:
private static async Task AwaitForeachExample()
{
// await foreach consumes an asynchronous stream. Each iteration can
// suspend while the next element is produced.
await foreach (int value in GenerateAsync())
{
Console.WriteLine(value); // => 0, then 1, then 2
}
}
private static async IAsyncEnumerable<int> GenerateAsync()
{
for (int i = 0; i < 3; i++)
{
await Task.Delay(1); // stand-in for real asynchronous work
yield return i;
}
}
Las secuencias asincrónicas se basan en async y await. Para ver un tutorial completo, consulte Generación y consumo de flujos asincrónicos.