Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Instrukcje iteracji –
Instrukcje iteracyjne wielokrotnie wykonują pojedynczą instrukcję lub blok instrukcji. Instrukcja for
wykonuje jego treść, podczas gdy określone wyrażenie logiczne daje wartość true
. Instrukcja foreach
wylicza elementy kolekcji i wykonuje jej treść dla każdego elementu kolekcji.
Instrukcjado
warunkowo wykonuje swoją treść raz lub więcej razy. Instrukcja while
warunkowo wykonuje treść zero lub więcej razy.
W dowolnym momencie w treści instrukcji iteracji można wyprowadzić pętlę przy użyciu instrukcjibreak
. Możesz przejść do następnej iteracji w pętli przy użyciu poleceniacontinue
.
Instrukcja for
Instrukcja for
wykonuje instrukcję lub blok instrukcji, podczas gdy określone wyrażenie logiczne oblicza wartość true
. W poniższym przykładzie pokazano instrukcję for
, która wykonuje jego treść, a licznik liczby całkowitej jest mniejszy niż trzy:
for (int i = 0; i < 3; i++)
{
Console.Write(i);
}
// Output:
// 012
W poprzednim przykładzie przedstawiono elementy instrukcji for
:
Sekcja inicjatora wykonywana tylko raz przed wejściem do pętli. Zazwyczaj deklarujesz i inicjujesz lokalną zmienną pętli w tej sekcji. Nie można uzyskać dostępu do zadeklarowanej zmiennej spoza instrukcji
for
.Sekcja inicjatora w poprzednim przykładzie deklaruje i inicjuje zmienną licznika liczb całkowitych:
int i = 0
Sekcja warunku określająca, czy należy wykonać następną iterację w pętli. Jeśli zostanie obliczona wartość
true
lub nie jest obecna, zostanie wykonana następna iteracja. W przeciwnym razie pętla zostanie zakończona. Sekcja warunku musi być wyrażeniem logicznym.Sekcja warunku w poprzednim przykładzie sprawdza, czy wartość licznika jest mniejsza niż trzy:
i < 3
Sekcja iteratora , która definiuje, co się dzieje po każdym wykonaniu treści pętli.
Sekcja iteratora w poprzednim przykładzie zwiększa licznik:
i++
Treść pętli, która musi być instrukcją lub blokiem instrukcji.
Sekcja iteratora może zawierać zero lub więcej instrukcji w formie wyrażeń, rozdzielonych przecinkami.
- Wyrażenie inkrementacji prefiksowej lub postfiksowej, takie jak lub
++i
- wyrażenie dekrementacji prefiksu lub postfiksu, na przykład
--i
lubi--
- przypisanie
- wywołanie metody
-
await
wyrażenie - tworzenie obiektu przy użyciu
new
operatora
Jeśli nie deklarujesz zmiennej pętli w sekcji inicjatora, możesz również użyć zera lub większej liczby wyrażeń z poprzedniej listy w sekcji inicjatora. W poniższym przykładzie pokazano kilka mniej typowych użycia sekcji inicjatora i iteratora: przypisywanie wartości do zmiennej zewnętrznej w sekcji inicjatora, wywoływanie metody w sekcjach inicjatora i iteratora oraz zmienianie wartości dwóch zmiennych w sekcji iteratora:
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
Wszystkie sekcje instrukcji for
są opcjonalne. Na przykład poniższy kod definiuje pętlę nieskończoną for
:
for ( ; ; )
{
//...
}
Instrukcja foreach
Instrukcja foreach
wykonuje instrukcję lub blok instrukcji dla każdego elementu w wystąpieniu typu implementującego System.Collections.IEnumerable lub System.Collections.Generic.IEnumerable<T> interfejs, jak pokazano w poniższym przykładzie.
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
Instrukcja nie jest ograniczona do tych typów foreach
. Można go używać z wystąpieniem dowolnego typu, które spełnia następujące warunki:
- Typ ma publiczną bezparametrową metodę
GetEnumerator
. MetodaGetEnumerator
może być metodą rozszerzenia typu. - Typ zwracany metody
GetEnumerator
ma publiczną właściwośćCurrent
oraz publiczną bezparametrową metodęMoveNext
, której typ zwracany tobool
.
Na przykładzie poniżej użyto instrukcji foreach
z wystąpieniem typu System.Span<T>, który nie implementuje żadnych interfejsów.
Span<int> numbers = [3, 14, 15, 92, 6];
foreach (int number in numbers)
{
Console.Write($"{number} ");
}
// Output:
// 3 14 15 92 6
Jeśli właściwość wyliczającej Current
zwraca referencyjną wartość zwracaną (ref T
gdzie T
jest typem elementu kolekcji), można zadeklarować zmienną iteracyjną za pomocą modyfikatora ref
lub ref readonly
, jak pokazano w poniższym przykładzie:
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
Jeśli kolekcja źródłowa instrukcji foreach
jest pusta, treść instrukcji foreach
nie jest wykonywana i pomijana. Jeśli instrukcja foreach
zostanie zastosowana do null
, zostanie zgłoszony wyjątek NullReferenceException.
await foreach
Możesz użyć instrukcji await foreach
, aby pobierać asynchroniczny strumień danych, czyli typ kolekcji, który implementuje interfejs IAsyncEnumerable<T>. Każda iteracja pętli może być zawieszona, gdy następny element jest pobierany asynchronicznie. W poniższym przykładzie pokazano, jak używać instrukcji await foreach
:
await foreach (var item in GenerateSequenceAsync())
{
Console.WriteLine(item);
}
Można również użyć instrukcji await foreach
z wystąpieniem dowolnego typu, które spełnia następujące warunki:
- Typ ma publiczną bezparametrową metodę
GetAsyncEnumerator
. Ta metoda może być metodą rozszerzającą typu. - Zwracany typ
GetAsyncEnumerator
metody ma właściwość publicznąCurrent
i publiczną metodę bezMoveNextAsync
parametrów, której zwracany typ toTask<bool>
,ValueTask<bool>
lub dowolny inny oczekiwany typ, którego metoda awaiterGetResult
zwracabool
wartość.
Domyślnie elementy strumienia są przetwarzane w przechwyconym kontekście. Jeśli chcesz wyłączyć przechwytywanie kontekstu, użyj TaskAsyncEnumerableExtensions.ConfigureAwait metody rozszerzenia. Aby uzyskać więcej informacji na temat kontekstów synchronizacji i przechwytywania bieżącego kontekstu, zobacz Korzystanie ze wzorca asynchronicznego opartego na zadaniach. Aby uzyskać więcej informacji na temat strumieni asynchronicznych, zobacz samouczek dotyczący strumieni asynchronicznych.
Typ zmiennej iteracji
Możesz użyć słowa kluczowego var
, aby kompilator mógł wnioskować typ zmiennej iteracji w instrukcji foreach
, jak pokazuje poniższy kod:
foreach (var item in collection) { }
Uwaga / Notatka
var
Typ elementu może być wywnioskowany przez kompilator jako typ odwołania dopuszczalny do wartości null, w zależności od tego, czy kontekst obsługujący wartość null jest włączony i czy typ wyrażenia inicjalizacji jest typem odwołania.
Aby uzyskać więcej informacji, zobacz lokalne zmienne o niejawnie określonym typie.
Można również jawnie określić typ zmiennej iteracji, jak pokazano w poniższym kodzie:
IEnumerable<T> collection = new T[5];
foreach (V item in collection) { }
W poprzednim formularzu typ T
elementu kolekcji musi być niejawnie lub jawnie konwertowany na typ V
zmiennej iteracji. Jeśli jawna konwersja z T
do V
kończy się niepowodzeniem, w czasie wykonywania instrukcja foreach
zgłasza wyjątek InvalidCastException. Na przykład jeśli T
jest typem klasy niezatieczętowanej, V
może być dowolny typ interfejsu, nawet ten, który T
nie implementuje. W czasie wykonywania typ elementu kolekcji może być takim, który jest pochodną elementu T
i faktycznie implementuje V
. Jeśli tak nie jest, InvalidCastException jest wyrzucany.
Instrukcja do
Instrukcja do
wykonuje instrukcję lub blok instrukcji, podczas gdy określone wyrażenie logiczne oblicza wartość true
. Ponieważ to wyrażenie jest obliczane po każdym wykonaniu pętli, pętla do
wykonuje co najmniej jeden raz. Pętla do
różni się od while
pętli, która wykonuje zero lub więcej razy.
W poniższym przykładzie pokazano użycie instrukcji do
:
int n = 0;
do
{
Console.Write(n);
n++;
} while (n < 5);
// Output:
// 01234
Instrukcja while
Instrukcja while
wykonuje instrukcję lub blok instrukcji, podczas gdy określone wyrażenie logiczne oblicza wartość true
. Ponieważ to wyrażenie jest oceniane przed każdym wykonaniem pętli, pętla while
może się wykonać zero razy lub więcej. Pętla while
różni się od do
pętli, która wykonuje się jeden lub więcej razy.
W poniższym przykładzie pokazano użycie instrukcji while
:
int n = 0;
while (n < 5)
{
Console.Write(n);
n++;
}
// Output:
// 01234
Specyfikacja języka C#
Aby uzyskać więcej informacji, zobacz następujące sekcje specyfikacji języka C#:
Aby uzyskać więcej informacji na temat tych funkcji, zobacz następujące uwagi dotyczące propozycji funkcji: