Распространённые ошибки при итерации
Изменение коллекции во время перебора.
«Распространённые ошибки при итерации» — бесплатный урок C# Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 4 уроков всего.
Проблемы при переборе
Циклы просты, но некоторые ошибки снова и снова сбивают начинающих с толку.
В этом уроке мы рассмотрим самые распространённые ошибки при переборе и способы их избежать.
Изменение во время перебора
Самая серьёзная ошибка — изменять коллекцию во время перебора с помощью foreach.
Добавление или удаление элементов во время перебора вызывает InvalidOperationException во время выполнения программы.
foreach (var n in list)
{
if (n < 0) list.Remove(n); // ERROR at runtime
}Безопасное решение
Чтобы удалять элементы во время цикла, перебирайте копию либо сначала соберите нужные элементы, а затем удалите их.
Перебор list.ToList() предоставляет отдельный снимок коллекции для обхода.
var list = new List<int> { 1, -2, 3, -4 };
foreach (var n in list.ToList())
{
if (n < 0) list.Remove(n);
}
Console.WriteLine(string.Join(",", list));Ошибка на единицу в циклах for
В ручном цикле for использование <= вместо < приводит к чтению за концом коллекции.
Допустимые индексы идут от 0 до Length - 1, поэтому условие должно быть таким: i < Length.
for (int i = 0; i <= arr.Length; i++) // BUG: <= goes too far
{
Console.WriteLine(arr[i]);
}IndexOutOfRange
Такая ошибка на единицу приводит к IndexOutOfRangeException.
foreach полностью исключает эту проблему, поскольку никогда не использует индекс. Предпочитайте его, когда требуется только читать элементы.
string[] arr = { "a", "b", "c" };
for (int i = 0; i < arr.Length; i++) // correct: < Length
{
Console.WriteLine(arr[i]);
}Ожидание, что foreach изменит элементы
Присваивание значения переменной цикла не изменяет коллекцию, а для типов-значений эта переменная в любом случае является копией.
Чтобы обновлять элементы, используйте цикл for с индексацией.
int[] nums = { 1, 2, 3 };
for (int i = 0; i < nums.Length; i++)
{
nums[i] = nums[i] * 10;
}
Console.WriteLine(string.Join(",", nums));Коллекция со значением null
Вызов foreach для ссылки со значением null вызывает NullReferenceException.
Пустая коллекция допустима, а null — нет. Перед циклом проверьте ссылку или инициализируйте коллекцию.
List<int> data = null;
if (data != null)
{
foreach (var x in data) Console.WriteLine(x);
}Путаница с областью видимости переменной
Переменная цикла существует только внутри тела цикла.
Попытка использовать её после цикла приводит к ошибке компиляции, поскольку после завершения цикла она выходит из области видимости.
foreach (var n in nums)
{
Console.WriteLine(n);
}
// Console.WriteLine(n); // ERROR: n not in scope hereЗабытые фигурные скобки
Без фигурных скобок циклу принадлежит только следующая отдельная инструкция.
Это может незаметно нарушить логику программы. Всегда используйте фигурные скобки для многострочных тел, чтобы намерение было очевидным.
foreach (var n in nums)
Console.WriteLine(n);
Console.WriteLine("runs once, not per item");Риск бесконечного цикла while
В отличие от foreach, цикл while может выполняться бесконечно, если его условие никогда не становится ложным.
Всегда проверяйте, что внутри цикла что-то изменяется и приближает выполнение к условию выхода.
int i = 0;
while (i < 3)
{
Console.WriteLine(i);
i++; // forgetting this would loop forever
}Выбор подходящего цикла
Нужно прочитать каждый элемент, индекс не требуется → foreach.
Нужен индекс или необходимо изменить элемент на месте → for. Нужно повторять действия, пока не изменится условие → while.
Быстрая проверка
Проверьте, что Вы узнали об ошибках при переборе.
Итоги
Вы научились избегать изменения коллекции во время foreach, ошибок на единицу с <=, проблем с коллекциями null и путаницы с областью видимости.
Выбирайте foreach для чтения, for для изменения по индексу, а while — для циклов, зависящих от условия и имеющих понятное условие выхода.
Часто задаваемые вопросы
Урок «Распространённые ошибки при итерации» бесплатный?
Да — полный текст урока «Распространённые ошибки при итерации» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 4 уроков всего.
Чему я научусь в уроке «Распространённые ошибки при итерации»?
Изменение коллекции во время перебора. Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C# Academy?
Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Распространённые ошибки при итерации»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C# Academy?
Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Цикл foreach
- Итерация по коллекциям
- break и continue
- Распространённые ошибки при итерации