вставка в очередь при ее перечислении
-
03-07-2019 - |
Вопрос
Я хочу выполнить поиск дерева в ширину, используя очередь.
var q = new Queue<T>();
q.Enqueue(Root);
foreach(T root in q)
{
foreach(T t in root.Children)
q.Enqueue(t);
}
Однако я получаю «коллекцию была изменена после того, как перечисление было создано». Исключение.
Есть ли тип C#, с которым я могу это сделать?
Редактировать:небольшое чтение заставляет меня задуматься, что я, возможно, делаю это совершенно неправильно.
Есть ли способ использовать foreach для исключения из очереди?
это работает, но некрасиво (ОМХО)
var q = new Queue<T>();
q.Enqueue(Root);
while(q.Count > 0)
{
T root = q.Dequeue();
foreach(T t in root.Children)
q.Enqueue(t);
}
Решение
Вы не можете перечислять IEnumerable и одновременно изменять один и тот же IEnumerable.Я не думаю, что существует коллекция C#, которая позволит это сделать.
Другие советы
А для каждого конструкция здесь не будет работать.
Решить проблему можно с помощью контейнера, обеспечивающего индексированный доступ.
var l = new List<T>();
l.Add(Root);
int i = 0;
while(i < l.Count)
{
T root = l[i];
foreach(T t in root.Children)
{
l.Add(t);
}
++i;
}
// And because you really wanted a queue
var q = new Queue<T>(l);
Не связан с StackOverflow