Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Tip
Este artigo faz parte da seção Conceitos Básicos para desenvolvedores que já conhecem pelo menos uma linguagem de programação e estão aprendendo C#. Se você é novo em programação, comece com os tutoriais Comece agora. Para ver a sintaxe completa, consulte as instruções de iteração na referência da linguagem.
Vindo de outro idioma? Todos os quatro loops C# (foreach, while,do-while e for) têm equivalentes diretos em Java, C++e JavaScript. Você usa foreach com mais frequência. Itera sobre uma coleção sem índice, como o for aprimorado do Java ou o for...of do JavaScript.
As instruções de iteração executam um bloco de código repetidamente. Cada passagem pelo bloco é uma iteração e um bloco repetido é um loop. O C# fornece quatro loops. Comece com foreach para coleções, use while e do-while quando uma condição controla a repetição, e use for quando precisar de um índice explícito.
Iterar uma coleção com foreach
A instrução foreach executa o corpo uma vez para cada elemento em uma coleção, em ordem. É a escolha mais comum para percorrer uma coleção porque você não precisa gerenciar um índice nem fazer a verificação dos limites. A instrução foreach impede erros off-by-one típicos:
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 com qualquer tipo que O C# reconhece como uma sequência, incluindo matrizes, List<T>e Dictionary<TKey,TValue>. A variável de iteração (name no exemplo anterior) é somente leitura, portanto, você não pode reatribuí-la dentro do loop.
O corpo de um loop é uma única instrução, como uma atribuição ou uma chamada de método. Uma instrução de bloco é, por si só, uma única instrução que delimita zero ou mais instruções entre chaves ({ }).
Muitos padrões de codificação recomendam que você delimite o corpo do loop com chaves, mesmo para uma única instrução. As chaves tornam o escopo explícito. Ele evita um erro comum: adicionar depois uma segunda linha que você espera que seja executada a cada iteração, mas que, em vez disso, é executada uma única vez depois do loop. Somente as chaves decidem quais instruções pertencem ao loop. C# não trata os espaços em branco como relevantes, portanto a indentação, por si só, nunca é suficiente. Chaves são legais mesmo em torno de uma linha: o bloco é a única instrução que o loop repete. Recue seu código para melhorar a legibilidade, mas use as chaves para definir o bloco.
Repita enquanto uma condição se mantém com while
Um while loop verifica sua condição booliana antes de cada iteração. Se a condição estiver false no início, o corpo nunca será executado, portanto, um loop while é executado zero ou mais vezes:
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--;
}
Verifique se algo dentro do loop altera a condição. No exemplo anterior, countdown-- eventualmente faz a condição false. Um loop cuja condição nunca se torna false é executado para sempre.
Execute o bloco pelo menos uma vez com do-while
Um loop do-while verifica a condição após cada iteração, de modo que o corpo sempre é executado pelo menos uma vez. Use-o quando a primeira execução precisar ocorrer antes que você possa avaliar a condição, como ao solicitar uma entrada e depois validá-la:
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 com for
Uma for instrução loop contém três partes: um inicializador que é executado uma vez antes do loop, uma condição que é verificada antes de cada iteração e um iterador que é executado após cada iteração. Use for quando precisar do índice em si, não apenas os elementos. Normalmente, você precisa do índice quando deseja modificar o elemento em vez de ler seu 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
}
Quando você apenas lê os elementos, sem usar as posições nem atribuir novos valores, prefira foreach. Ele indica a intenção com mais clareza e evita a aritmética do índice.
Sair ou ignorar com break e continue
Duas instruções de salto oferecem um controle mais fino dentro de qualquer loop. A break instrução sai do loop imediatamente, ignorando todas as iterações 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;
}
}
A continue instrução ignora o restante da iteração atual e passa para a próxima:
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
}
Iterar um fluxo assíncrono com await foreach
Um fluxo assíncrono é um leitor que usa uma tarefa assíncrona para produzir cada próximo elemento. O C# representa-o com a IAsyncEnumerable<T> interface. Os dados que chegam ao longo do tempo, como páginas de uma API Web ou linhas de um banco de dados, se ajustam a esse modelo: recuperar o próximo elemento é uma operação aguardada em vez de um retorno imediato.
Para consumir um fluxo assíncrono, coloque a await palavra-chave antes foreach. Cada iteração aguarda o próximo elemento, de modo que o loop seja suspenso enquanto esse elemento é produzido em vez de bloquear o thread:
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;
}
}
Os fluxos assíncronos se baseiam em async e await. Para obter um passo a passo completo, consulte Gerar e consumir fluxos assíncronos.