Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Операторы итерации —
Операторы итерации многократно выполняют инструкцию или блок инструкций. Оператор for выполняет текст, пока указанное логическое выражение вычисляется true. Инструкция foreach перечисляет элементы коллекции и выполняет его текст для каждого элемента коллекции. Оператор do условно выполняет свой текст один или несколько раз. Оператор while условно выполняет тело ноль или более раз.
В любой момент в тексте инструкции итерации можно выйти из цикла с помощью инструкцииbreak. Вы можете перейти к следующей итерации в цикле с помощью инструкцииcontinue.
Инструкция for
Оператор for выполняет оператор или блок операторов, пока указанное логическое выражение вычисляется в true. В следующем примере показан оператор for, который выполняет его код, пока целочисленный счетчик меньше трех.
for (int i = 0; i < 3; i++)
{
Console.Write(i);
}
// Output:
// 012
В предыдущем примере показаны элементы инструкции for :
Раздел инициализатора , который выполняется только один раз перед вводом цикла. Как правило, вы объявляете и инициализируете локальную переменную цикла в этом разделе. Объявленная переменная не может быть доступна из-за пределов инструкции
for.Раздел инициализатора в предыдущем примере объявляет и инициализирует целочисленную переменную счетчика:
int i = 0Раздел условия , определяющий, следует ли выполнять следующую итерацию в цикле. Если значение равно
trueили отсутствует, выполняется следующая итерация; иначе цикл завершается. Раздел условия должен быть логическим выражением.Раздел условия в предыдущем примере проверяет, является ли значение счетчика меньше трех.
i < 3Раздел итератора, определяющий, что происходит после каждого выполнения тела цикла.
Раздел итератора в предыдущем примере увеличивает счетчик:
i++Тело цикла, которое должно быть операцией или блоком инструкций.
Раздел итератора может содержать ноль или более следующих выражений инструкций, разделенных запятыми:
-
префиксное или постфиксное инкрементное выражение, например
++iилиi++ - выражение префиксного или постфиксного декремента, например
--iилиi-- - задание
- вызов метода
-
awaitВыражение - создание объекта с помощью
newоператора
Если вы не объявляете переменную цикла в разделе инициализатора, можно также использовать ноль или больше выражений из предыдущего списка в разделе инициализатора. В следующем примере показано несколько менее распространенных вариантов использования инициализатора и итератора: назначение значения внешней переменной в разделе инициализатора, вызов метода в разделах инициализатора и итератора и изменение значений двух переменных в разделе итератора:
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
Все разделы инструкции for являются необязательными. Например, следующий код определяет бесконечный for цикл:
for ( ; ; )
{
//...
}
Инструкция foreach
Инструкция foreach выполняет инструкцию или блок инструкций для каждого элемента в экземпляре типа, реализующего System.Collections.IEnumerable или System.Collections.Generic.IEnumerable<T> интерфейс, как показано в следующем примере:
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
Оператор foreach не ограничивается этими типами. Его можно использовать с экземпляром любого типа, удовлетворяющего следующим условиям:
- Тип имеет публичный метод без параметров
GetEnumerator. ЭтотGetEnumeratorметод может быть методом расширения. - Возвращаемый тип метода
GetEnumeratorвключает в себя общедоступное свойствоCurrentи открытый методMoveNextбез параметров, чей возвращаемый тип —bool.
В следующем примере используется foreach инструкция с экземпляром System.Span<T> типа, который не реализует интерфейсы.
Span<int> numbers = [3, 14, 15, 92, 6];
foreach (int number in numbers)
{
Console.Write($"{number} ");
}
// Output:
// 3 14 15 92 6
Если свойство перечислителя Current возвращает возвращаемое значение ссылки (ref T где T тип элемента коллекции), можно объявить переменную итерации с refref readonly модификатором, как показано в следующем примере:
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
Если исходная коллекция инструкции foreach пуста, текст инструкции foreach не выполняется и пропускается. Если оператор foreach применяется к null, NullReferenceException выбрасывается исключение.
Оператор "await foreach"
Инструкцию await foreach можно использовать для использования асинхронного потока данных, то есть типа коллекции, реализующего IAsyncEnumerable<T> интерфейс. Каждая итерация цикла может быть приостановлена, пока следующий элемент извлекается асинхронно. В следующем примере показано, как использовать инструкцию await foreach :
await foreach (var item in GenerateSequenceAsync())
{
Console.WriteLine(item);
}
Инструкцию await foreach можно также использовать с экземпляром любого типа, удовлетворяющего следующим условиям:
- Тип имеет публичный метод без параметров
GetAsyncEnumerator. Этот метод может быть членом расширения. - Возвращаемый тип метода
GetAsyncEnumeratorимеет общедоступное свойствоCurrentи открытый метод без параметровMoveNextAsync, возвращаемый тип которого являетсяTask<bool>,ValueTask<bool>, или любой другой ожидающий тип, методGetResultожидающего возвращает значениеbool.
По умолчанию элементы потока обрабатываются в захваченном контексте. Если вы хотите отключить запись контекста, используйте TaskAsyncEnumerableExtensions.ConfigureAwait метод расширения. Дополнительные сведения о контекстах синхронизации и записи текущего контекста см. в статье "Использование асинхронного шаблона на основе задач". Дополнительные сведения об асинхронных потоках см. в руководстве по асинхронным потокам.
Тип переменной итерации
Ключевое var слово позволяет компилятору определить тип переменной итерации в foreach инструкции, как показано в следующем коде:
foreach (var item in collection) { }
Замечание
Тип var объявления можно вывести компилятором в качестве ссылочного типа, допускающего значение NULL, в зависимости от того, включен ли контекст с поддержкой null и является ли тип выражения инициализации ссылочным типом.
Дополнительные сведения см. в разделе неявно типизированные локальные переменные.
Можно также явно указать тип переменной итерации, как показано в следующем коде:
IEnumerable<T> collection = new T[5];
foreach (V item in collection) { }
В предыдущей форме тип T элемента коллекции должен быть неявно или явно преобразован в тип V переменной итерации. Если при выполнении явное преобразование из T в V не удается, оператор foreach вызывает исключение InvalidCastException. Например, если T это непечатанный тип класса, может быть любой тип интерфейса, V даже тот, который T не реализует. Во время выполнения тип элемента коллекции может быть производным от T и фактически реализующим V. Если это не так, InvalidCastException выбрасывается исключение.
Инструкция do
Оператор do выполняет оператор или блок операторов, пока указанное логическое выражение вычисляется в true. Так как это выражение вычисляется после каждого выполнения цикла, do цикл выполняется один или несколько раз. Цикл do отличается от while цикла, который выполняется один или более раз.
В следующем примере показано использование инструкции do :
int n = 0;
do
{
Console.Write(n);
n++;
} while (n < 5);
// Output:
// 01234
Инструкция while
Оператор while выполняет оператор или блок операторов, пока указанное логическое выражение вычисляется в true. Так как это выражение вычисляется перед каждым выполнением цикла, while цикл выполняется от нуля и более раз. Цикл while отличается от do цикла, который выполняется один или несколько раз.
В следующем примере показано использование инструкции while :
int n = 0;
while (n < 5)
{
Console.Write(n);
n++;
}
// Output:
// 01234
Спецификация языка C#
Дополнительные сведения см. в следующих разделах статьи Спецификация языка C#:
-
Инструкция
for -
Инструкция
foreach -
Инструкция
do -
Инструкция
while -
Поддержка расширения
GetEnumeratorдля цикловforeach
См. также
- декларации
- итераторы