1.foreach и для
Цикл foreach
работает с IEnumerator , когда цикл for
работает с индексом (в object myObject = myListOfObjects[i]
, i - индекс).
Между ними существует большая разница:
индекс может напрямую обращаться к любому объекту в зависимости от его положения в списке.
перечислитель может получить доступ только к первому элементу списка, а затем перейти к следующему элементу (как описано в предыдущей ссылке из msdn).Он не может получить доступ к элементу напрямую, просто зная индекс элемента в списке.
Так что перечислитель может показаться менее мощным, но:
- выне всегда знают положение элементов в группе, потому что все группы не упорядочены / не проиндексированы.
- вы не всегда знаете количество элементов в списке (подумайте о связанном списке).
- , даже когда он упорядочен, индексированный доступ к списку может быть основан на внутреннем перечислителе, что означает, что каждый раз, когда вы обращаетесь к элементу по его позиции, вы можете фактически перечислять все элементы списка вплоть доэлемент, который вы хотите.
- индексы не всегда числовые.Подумайте о словаре .
Так что на самом деле большая сила цикла foreach
и базовое использование IEnumerator
заключается в том, что он применяется к любому типу, который реализует IEnumerable
(реализация IEnumerable означает, что вы предоставляете метод, который возвращает перечислитель).Списки, массивы, словари и все другие типы групп реализуют IEnumerable.И вы можете быть уверены, что перечислитель, который у них есть, не уступает: вы не найдете самый быстрый способ просмотреть список.
Итак, цикл for
может обычно следует рассматривать как специализированный foreach
цикл:
public void GoThrough(List<object> myList)
{
for (int i=0; i<myList.Count; i++)
{
MessageBox.Show(myList[i].ToString());
}
}
совершенно эквивалентен:
public void GoThrough(List<object> myList)
{
foreach (object item in myList)
{
MessageBox.Show(item.ToString());
}
}
Я сказал обычно , потому что есть очевидный случайкогда необходим цикл for
: когда по какой-то причине (например, при его отображении) вам нужен индекс (то есть позиция в списке) объекта.Однако в конечном итоге вы поймете, что это происходит только в определенных случаях , когда вы хорошо программируете .NET, и что foreach
должен быть вашим кандидатом по умолчанию для циклов над группой элементов.
Теперь, чтобы продолжать сравнивать цикл foreach
, он действительно очень интересен: цикл
public void GoThrough(IEnumerable myEnumerable)
{
foreach (object obj in myEnumerable)
{
MessageBox.Show(obj.ToString());
}
}
полностью эквивалентен:
public void GoThrough(IEnumerable myEnumerable)
{
IEnumerator myEnumerator = myEnumerable.GetEnumerator();
while (myEnumerator.MoveNext())
{
MessageBox.Show(myEnumerator.Current.ToString());
}
}
Первая запись - этонамного проще, хотя.
2.while и do.. while
Цикл while (condition) {action}
и цикл do {action} while (condition)
просто отличаются друг от друга тем, что первый проверяет условие перед применением действия, когда второйприменяет действие, затем проверяет условие.Цикл do {..} while (..)
используется весьма незначительно по сравнению с другими, поскольку он выполняет действие по крайней мере один раз, даже если условие изначально не выполняется (что может привести к проблемам, поскольку действие обычно зависит от условия).
Цикл while
является более общим, чем циклы for
и foreach
, которые применяются конкретно к спискам объектов.Цикл while
просто имеет условие для продолжения, которое может основываться на чем угодно.Например:
string name = string.empty;
while (name == string.empty)
{
Console.WriteLine("Enter your name");
name = Console.ReadLine();
}
просит пользователя ввести его имя, затем нажимать Enter, пока он на самом деле что-то не введет.Как видите, ничего общего со списками не имеет.
3.Заключение
Когда вы просматриваете список, вы должны использовать foreach
, если вам не нужен числовой индекс, в этом случае вы должны использовать for
.Если это не имеет ничего общего со списком, а является процедурной конструкцией, вам следует использовать while(..) {..}
.
Теперь закончим чем-то менее ограничительным: ваша первая цель в .NET должна состоять в том, чтобы сделать ваш код читабельным / поддерживаемым и , чтобы он работал быстро в том порядке приоритета.Все, что достигает, это хорошо для вас.Лично я думаю, что цикл foreach
имеет то преимущество, что потенциально он наиболее читаемый и самый быстрый.
Edit: есть другой случай, когдацикл for
полезен: когда вам нужно индексировать, чтобы пройти по списку особым образом, или если вам нужно изменить список в цикле.Например, в этом случае, потому что мы хотим удалить каждый нулевой элемент из myList:
for (int i=myList.Count-1; i>=0; i--)
{
if (myList[i] == null) myList.RemoveAt(i);
}
Вам нужен цикл for
, потому что myList нельзя изменить из цикла foreach
, и нам нужноперейти назад, потому что, если вы удалите элемент в позиции i, положение всех элементов с индексом> i изменится.
Но использование этих специальных конструкций было сокращено после LINQ.Последний пример может быть написан так в LINQ, например:
myList.RemoveAll(obj => obj == null);
LINQ - это второй шаг, сначала изучите циклы.