Foreach c что это

Цикл do. . . while

Цикл do. while в C# — это версия while с постпроверкой условия. Это значит, что условие цикла проверяется после выполнения тела цикла. Следовательно, циклы do. while удобны в тех ситуациях, когда блок операторов должен быть выполнен как минимум однажды. Ниже приведена общая форма оператора цикла do-while:

При наличии лишь одного оператора фигурные скобки в данной форме записи необязательны. Тем не менее они зачастую используются для того, чтобы сделать конструкцию do-while более удобочитаемой и не путать ее с конструкцией цикла while. Цикл do-while выполняется до тех пор, пока условное выражение истинно. В качестве примера использования цикла do-while можно привести следующую программу, расчитывающую факториал числа:

Цикл foreach

Цикл foreach служит для циклического обращения к элементам коллекции, представляющей собой группу объектов. В C# определено несколько видов коллекций, каждая из которых является массивом. Ниже приведена общая форма оператора цикла foreach:

Здесь тип имя_переменной_цикла обозначает тип и имя переменной управления циклом, которая получает значение следующего элемента коллекции на каждом шаге выполнения цикла foreach. А коллекция обозначает циклически опрашиваемую коллекцию, которая здесь и далее представляет собой массив. Следовательно, тип переменной цикла должен соответствовать типу элемента массива. Кроме того, тип может обозначаться ключевым словом var. В этом случае компилятор определяет тип переменной цикла, исходя из типа элемента массива. Это может оказаться полезным для работы с определенного рода запросами. Но, как правило, тип указывается явным образом.

Оператор цикла foreach действует следующим образом. Когда цикл начинается, первый элемент массива выбирается и присваивается переменной цикла. На каждом последующем шаге итерации выбирается следующий элемент массива, который сохраняется в переменной цикла. Цикл завершается, когда все элементы массива окажутся выбранными.

Оператор foreach выполняет оператор или блок операторов для каждого элемента в экземпляре типа, который реализует интерфейс System.Collections.IEnumerable или System.Collections.Generic.IEnumerable . The foreach statement executes a statement or a block of statements for each element in an instance of the type that implements the System.Collections.IEnumerable or System.Collections.Generic.IEnumerable interface. Оператор foreach не ограничивается этими типами. Он может применяться к экземпляру любого типа, который удовлетворяет следующим условиям: The foreach statement is not limited to those types and can be applied to an instance of any type that satisfies the following conditions:

  • включает открытый метод GetEnumerator без параметров со следующим типом возвращаемого значения: класс, структура или тип интерфейса; has the public parameterless GetEnumerator method whose return type is either class, struct, or interface type,
  • тип возвращаемого значения метода GetEnumerator должен содержать открытое свойство Current и открытый метод MoveNext без параметров с типом возвращаемого значения Boolean. the return type of the GetEnumerator method has the public Current property and the public parameterless MoveNext method whose return type is Boolean.

Начиная с версии C# 7.3, если свойство перечислителя Current возвращает ссылочное возвращаемое значение ( ref T , где T — это тип элемента коллекции), вы можете объявить переменную итерации с модификатором ref или ref readonly . Beginning with C# 7.3, if the enumerator’s Current property returns a reference return value ( ref T where T is the type of the collection element), you can declare the iteration variable with the ref or ref readonly modifier.

В любой момент в блоке операторов foreach вы можете прервать цикл с помощью оператора break или перейти к следующей итерации в цикле с помощью оператора continue. At any point within the foreach statement block, you can break out of the loop by using the break statement, or step to the next iteration in the loop by using the continue statement. Также можно выйти из цикла foreach с помощью операторов goto, return или throw. You also can exit a foreach loop by the goto, return, or throw statements.

Если оператор foreach применяется к null , возникает исключение NullReferenceException. If the foreach statement is applied to null , a NullReferenceException is thrown. Если исходная коллекция инструкции foreach пустая, тело цикла foreach не выполняется и пропускается. If the source collection of the foreach statement is empty, the body of the foreach loop is not executed and skipped.

Примеры Examples

Примеры C# в этой статье выполняются во встроенном средстве выполнения кода и на площадке Try.NET. The C# examples in this article run in the Try.NET inline code runner and playground. Нажмите на кнопку Выполнить, чтобы выполнить пример в интерактивном окне. Select the Run button to run an example in an interactive window. После выполнения кода вы можете изменить его и выполнить измененный код, снова нажав на кнопку Выполнить. Once you execute the code, you can modify it and run the modified code by selecting Run again. Либо в интерактивном окне выполняется измененный код, либо, если компиляция завершается с ошибкой, в интерактивном окне отображаются все сообщения об ошибках компилятора C#. The modified code either runs in the interactive window or, if compilation fails, the interactive window displays all C# compiler error messages.

В следующем примере показано использование оператора foreach с экземпляром типа List , который реализует интерфейс IEnumerable : The following example shows usage of the foreach statement with an instance of the List type that implements the IEnumerable interface:

В следующем примере показано использование оператора foreach с экземпляром типа System.Span , который не реализует интерфейс: The next example uses the foreach statement with an instance of the System.Span type, which doesn’t implement any interfaces:

В следующем примере с помощью переменной итерации ref устанавливается значение каждого элемента в массиве stackalloc. The following example uses a ref iteration variable to set the value of each item in a stackalloc array. В версии ref readonly выполняется перебор коллекции для печати всех значений. The ref readonly version iterates the collection to print all the values. В объявлении readonly используется неявное объявление локальной переменной. The readonly declaration uses an implicit local variable declaration. Неявные объявления переменных могут использоваться с объявлениями ref или ref readonly , так же как и явно типизированные объявления переменных. Implicit variable declarations can be used with either ref or ref readonly declarations, as can explicitly typed variable declarations.

Спецификация языка C# C# language specification

Дополнительные сведения см. в разделе Оператор foreach в документации Предварительная спецификация C# 6.0. For more information, see The foreach statement section of the C# language specification.

Начал самообучение C#.
Никак не пойму, для чего нужны for, foreach (точнее, вроде как понимаю, но не совсем). Покажите наглядный пример для чего они нужны, понятный даже для того кто не учит яп.

3 ответа 3

С нуля так с нуля. Значит пойдем с самого начала.

Для начала разберемся с циклом for

Возьмем самый простой пример, допустим вы хотите вывести числа от 0 до 9 построчно.

Очевидно, что можно сделать так:

Результат конечно достигнут, но что делать если чисел не 10, а 10000?

Ок, попробуем обойтись совсем старыми средствами (данный код строго демонстрационный, хоть он и работает, использовать его не надо нигде и никогда)

Цель достигнута? Безусловно. Но почему этот код плохой? Представьте что в вашей программе не одна метка, а пара десятков, запутаться какая для чего и когда именно на нее будет возврат проще простого. Читать такой код очень тяжело, искать ошибки еще тяжелее. Хотя надо отметить что на самом нижнем уровне оно именно так и работает, но у нас же язык высокого уровня, значит должны быть более простые и понятные человеку конструкции. И они есть, в первую очередь универсальный, во всех смыслах, цикл while :

От предыдущего кода отличается только отсутствием метки и ключевым словом while вместо if . Границы блока, который будет выполняться несколько раз, задают фигурные скобки. Хорошо? И да, и нет, потому что у нас все еще остается место потенциальной ошибки — это изменение счетчика. Оно должно происходить в самом конце повторяющегося блока, а условие выполнения находится в самом начале. Если кода в повторяющемся блоке много, то можно случайно забыть про необходимость поменять счетчик или изменить его не так как нужно и цикл превратится в вечный.

Последняя проблема решается с помощью цикла for :

Как видите, и начальное значение счетчика, и условие, и правило изменения счетчика задаются в одной конструкции максимально близко друг к другу, что позволяет сразу заметить ошибку не бегая по всему коду цикла.

Для компилятора и CLR, которая будет выполнять ваш код, разницы между этими вариантами абсолютно никакой, но исходный код программы должен быть понятен человеку, который будет его читать и отлаживать. Поэтому в рассмотренном примере использование цикла ‘for’ предпочтительнее.

Теперь посмотрим что скрывается за конструкцией foreach . Некоторые вещи будут вам незнакомы, поэтому для начала сравните понятность полученного кода, а потом разберитесь с незнакомыми классами и методами с помощью документации.

И так, допустим у нас есть некоторая коллекция объектов, например чисел List . Нам не важно какие там числа, в каком порядке, мы просто хотим вывести их все. Разумеется можно воспользоваться циклом for и доставать элементы из коллекции по их порядковому номеру.

Однако, далеко не все коллекции позволяют обращаться к своим элементам по порядковому номеру, т.к. этого номера может и не быть. А еще есть перечисления ( IEnumerable , IEnumerable ), у которых даже своих элементов нет, они предоставляют избранные элементы какой-то другой коллекции или вообще генерируют их налету. Что делать? Воспользуемся перечислителем ( IEnumerator , IEnumerator ) и циклом while :

Цель достигнута? Да, но. для того, чтобы понять с чем мы вообще работаем, нужно найти в коде объявление нашей коллекции и посмотреть из каких элементов она состоит. В общем работает, но читать такое, мягко говоря, не комфортно. А если код не такой простой как в нашем примере, то вообще мрак.

Вот тут и понадобится цикл foreach :

Не трудно заметить, что в таком варианте однозначно понятен и тип элементов, с которыми будем работать, и из какой они коллекции, и ни какого вспомогательного кода в явном виде не присутствует. Разумеется, как и в случае с циклом for , компилятор все равно развернет ваш foreach именно в ту, неудобную для чтения, конструкцию, да еще и с метками, вместо понятного while , но это проблемы компилятора, своей цели мы добились — код краток и понятен человеку.

Ну вот как-то так. Если кто-то может дополнить и/или найдет неточности, дайте знать в комментариях, внесу правки.

PS: Я в курсе, что конструкция под капотом foreach более забористая, но намерено не стал приводить полную развертку, т.к. считаю, что для понимания полезности foreach этого должно быть достаточно.


[an error occurred while processing the directive]
Карта сайта