Изменение коллекции foreach

Рейтинг: 2Ответов: 1Опубликовано: 31.03.2015

Есть конструкция вида:

while(!found)
{
 foreach(Tile tile in incoming_tiles)
 {
  //обработка входящего List
 }
 incoming_tiles=outcoming_tiles;
}

Формирование outcoming_tiles происходит внутри foreach, изменение переменной found происходит там же

При попытке прогнать код, на второй иттерации выдает ошибку "коллекция была изменена". Знаю, что подобное возникает когда коллекцию пытаешься изменить внутри foreach, но не могу понять, почему нельзя её менять вне foreach и снова подавать на вход в цикле.

Хотелось бы узнать, в чем дело и как это можно обойти, заранее спасибо.

UP: Полный код цикла

        while (!found)
        {
                foreach (Position tile in incoming)
                {
                    if (tile.X < map.GetLength(0) &&
                        tile.X > 0 &&
                        tile.Y < map.GetLength(1) &&
                        tile.Y > 0)
                    {
                        for (int i = tile.X - 1; i <= tile.X + 1; i++)
                        {
                            if (i == tile.X)
                            {
                                for (int j = tile.Y - 1; j <= tile.Y + 1; j += 2)
                                {
                                    if (map[i, j] == 0)
                                    {
                                        waved[i, j] = wave;
                                        outcoming.Add(new Position(i, j));
                                        if (i == end.X && j == end.Y)
                                        {
                                            found = true;
                                            break;
                                        }
                                    }
                                }
                            }
                            if (map[i, tile.Y] == 0)
                            {
                                waved[i, tile.Y] = wave;
                                outcoming.Add(new Position(i, tile.Y));
                                if (i == end.X && tile.Y == end.Y)
                                {
                                    found = true;
                                    break;
                                }
                            }
                        }
                    }
                }
            incoming = outcoming;
            wave++;
        }

Ответы

▲ 1
  1. Вы итерируетесь по коллекции incoming.
  2. В цикле вы добавляете в коллекцию outcoming новые элементы.
  3. После цикла вы присваиваете переменной incoming ссылку на коллекцию outcoming.
  4. В новой итерации при добавлении элементов в outcoming изменяется также и коллекция incoming, поскольку обе переменные указывают на одну и ту же коллекцию.

Чтобы решить эту проблему, нужно вместо присвоения ссылки

incoming = outcoming;

создать новую коллекцию с теми же элементами

incoming = new List<Position>(outcoming);