Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Instruções de iteração -
As instruções de iteração executam repetidamente uma instrução ou um bloco de instruções. A for
instrução executa seu corpo enquanto uma expressão booleana especificada é avaliada como true
. A foreach
instrução enumera os elementos de uma coleção e executa seu corpo para cada elemento da coleção. A do
instrução executa condicionalmente seu corpo uma ou mais vezes. A while
instrução executa condicionalmente seu corpo zero ou mais vezes.
Em qualquer ponto dentro do corpo de uma instrução de iteração, você pode sair do loop usando a break
instrução. Você pode passar para a próxima iteração no loop usando a continue
instrução.
Declaração for
A for
instrução executa uma instrução ou um bloco de instruções, enquanto uma expressão booleana especificada é avaliada como true
. O exemplo a seguir mostra a for
instrução que executa seu corpo enquanto um contador inteiro é menor que três:
for (int i = 0; i < 3; i++)
{
Console.Write(i);
}
// Output:
// 012
O exemplo anterior mostra os elementos for
da instrução:
A seção do inicializador que é executada apenas uma vez, antes de entrar no loop. Normalmente, você declara e inicializa uma variável de loop local nessa seção. A variável declarada não pode ser acessada de fora da
for
instrução.A seção inicializador no exemplo anterior declara e inicializa uma variável de contador inteiro:
int i = 0
A seção de condição que determina se a próxima iteração no loop deve ser executada. Se ele for avaliado como
true
ou não estiver presente, a próxima iteração será executada; caso contrário, o loop será encerrado. A seção de condição deve ser uma expressão booleana.A seção de condição no exemplo anterior verifica se um valor de contador é menor que três:
i < 3
A seção iterador que define o que acontece após cada execução do corpo do loop.
A seção iterador no exemplo anterior incrementa o contador:
i++
O corpo do loop, que deve ser uma instrução ou um bloco de instruções.
A seção iterador pode conter zero ou mais das seguintes expressões de declaração, separadas por vírgulas.
- expressão de incremento em forma de prefixo ou sufixo, como
++i
oui++
- Expressão de decréscimo em prefixo ou sufixo, como ou
--i
- Atribuição
- Invocação de um método
-
await
expressão - Criação de um objeto usando o
new
operador
Se você não declarar uma variável de loop na seção inicializador, poderá usar zero ou mais expressões da lista anterior na seção inicializador também. O exemplo a seguir mostra vários usos menos comuns das seções inicializador e iterador: atribuir um valor a uma variável externa na seção inicializador, invocar um método nas seções inicializador e iterador e alterar os valores de duas variáveis na seção 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 as secções da for
declaração são opcionais. Por exemplo, o código a seguir define o loop infinito for
:
for ( ; ; )
{
//...
}
Declaração foreach
A foreach
instrução executa uma instrução ou um bloco de instruções para cada elemento em uma instância de um tipo que implementa a interface System.Collections.IEnumerable ou a interface System.Collections.Generic.IEnumerable<T>, como mostra o exemplo a seguir.
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
A foreach
declaração não se limita a esses tipos. Você pode usá-lo com uma instância de qualquer tipo que satisfaça as seguintes condições:
- Um tipo tem o método público sem parâmetros
GetEnumerator
. OGetEnumerator
método pode ser o método de extensão de um tipo. - O tipo de retorno do método
GetEnumerator
tem a propriedade públicaCurrent
e o método público sem parâmetrosMoveNext
cujo tipo de retorno ébool
.
O exemplo a seguir usa a foreach
instrução com uma instância do System.Span<T> tipo, que não implementa nenhuma interface:
Span<int> numbers = [3, 14, 15, 92, 6];
foreach (int number in numbers)
{
Console.Write($"{number} ");
}
// Output:
// 3 14 15 92 6
Se a propriedade do Current
enumerador devolver um valor de retorno de referência (ref T
onde T
representa o tipo de um elemento da coleção), pode declarar uma variável de iteração com os modificadores ref
ou ref readonly
, conforme demonstra o exemplo a seguir:
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
Se a coleção de origem da foreach
instrução estiver vazia, o corpo da foreach
instrução não será executado e ignorado. Se a foreach
instrução for aplicada a null
, a NullReferenceException é lançada.
aguardar por cada um
Você pode usar a await foreach
instrução para consumir um fluxo assíncrono de dados, ou seja, o tipo de coleção que implementa a IAsyncEnumerable<T> interface. Cada iteração do loop pode ser suspensa enquanto o próximo elemento é recuperado de forma assíncrona. O exemplo a seguir mostra como usar a await foreach
instrução:
await foreach (var item in GenerateSequenceAsync())
{
Console.WriteLine(item);
}
Você também pode usar o await foreach
comando com uma instância de qualquer tipo que satisfaça as seguintes condições:
- Um tipo tem o método público sem parâmetros
GetAsyncEnumerator
. Esse método pode ser o método de extensão de um tipo. - O tipo de retorno do método
GetAsyncEnumerator
tem a propriedade públicaCurrent
e o método público sem parâmetrosMoveNextAsync
, cujo tipo de retorno éTask<bool>
,ValueTask<bool>
ou qualquer outro tipo aguardável cujo método do awaiterGetResult
retorna um valorbool
.
Por padrão, os elementos de fluxo são processados no contexto capturado. Se você quiser desativar a captura do contexto, use o TaskAsyncEnumerableExtensions.ConfigureAwait método de extensão. Para obter mais informações sobre contextos de sincronização e captura do contexto atual, consulte Consumindo o padrão assíncrono baseado em tarefas. Para obter mais informações sobre fluxos assíncronos, consulte o tutorial Fluxos assíncronos.
Tipo de uma variável de iteração
Você pode usar a var
palavra-chave para permitir que o compilador infera o tipo de uma variável de iteração na foreach
instrução, como mostra o código a seguir:
foreach (var item in collection) { }
Observação
O tipo de var
pode ser inferido pelo compilador como um tipo de referência anulável, dependendo se o contexto consciente de nulidade está habilitado e se o tipo de uma expressão de inicialização é um tipo de referência.
Para obter mais informações, consulte Variáveis locais digitadas implicitamente.
Você também pode especificar explicitamente o tipo de uma variável de iteração, como mostra o código a seguir:
IEnumerable<T> collection = new T[5];
foreach (V item in collection) { }
Na forma anterior, o tipo T
de um elemento de coleção deve ser implícita ou explicitamente convertível em tipo V
de uma variável de iteração. Se uma conversão explícita de T
para V
falhar em tempo de execução, a instrução foreach
lançará uma InvalidCastException. Por exemplo, se T
for um tipo de classe não lacrada, V
pode ser qualquer tipo de interface, mesmo aquela que T
não implementa. Em tempo de execução, o tipo de um elemento de coleção pode ser aquele que deriva de T
e realmente implementa V
. Se não for esse o caso, um InvalidCastException é gerado.
Declaração do
A do
instrução executa uma instrução ou um bloco de instruções, enquanto uma expressão booleana especificada é avaliada como true
. Como essa expressão é avaliada após cada execução do loop, um do
loop é executado uma ou mais vezes. O do
loop difere do while
loop, que executa zero ou mais vezes.
O exemplo a seguir mostra o uso da do
instrução:
int n = 0;
do
{
Console.Write(n);
n++;
} while (n < 5);
// Output:
// 01234
Declaração while
A while
instrução executa uma instrução ou um bloco de instruções, enquanto uma expressão booleana especificada é avaliada como true
. Como essa expressão é avaliada antes de cada execução do loop, um while
loop é executado zero ou mais vezes. O while
loop difere do do
loop, que é executado uma ou mais vezes.
O exemplo a seguir mostra o uso da while
instrução:
int n = 0;
while (n < 5)
{
Console.Write(n);
n++;
}
// Output:
// 01234
Especificação da linguagem C#
Para obter mais informações, consulte as seguintes seções da especificação da linguagem C#:
Para obter mais informações sobre esses recursos, consulte as seguintes notas de proposta de recurso: