2009-03-02 4 views
0

ich eine Breitensuche eines Baumes mit einer QueueEinfügen in eine Warteschlange, während er aufzählt

var q = new Queue<T>(); 

q.Enqueue(Root); 

foreach(T root in q) 
{ 
    foreach(T t in root.Children) 
    q.Enqueue(t); 
} 

Allerdings erhalte ich eine tun will „Collection wurde geändert, nachdem die enumerator instanziiert wurde.“ Ausnahme.

Gibt es einen C# -Typ, mit dem ich das machen kann?


Edit: ein wenig lesen machen mich Sache, ich könnte das total falsch machen.

Gibt es eine Möglichkeit, eine Foreach aus einer Warteschlange herauszuziehen?


das funktioniert, ist aber hässlich (OMHO)

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); 
} 
+0

Was macht Ihr Arbeitsbeispiel effektiv? Wenn ich etwas nicht verpasse, fügen Sie fortwährend Dinge hinzu und entfernen dann Elemente, die schließlich mit einer leeren Warteschlange enden. Soll die Verarbeitung nach dem "Dequeue" -Befehl erfolgen? –

Antwort

8

Sie können eine IEnumerable nicht aufzählen über und die gleiche IEnumerable zur gleichen Zeit ändern. Ich denke nicht, dass es eine C# -Kollektion gibt, die dies erlaubt.

+0

'Observable.ToEnumerable()' :) – Benjol

2

Das foreach Konstrukt wird hier nicht funktionieren.

Sie können das Problem mithilfe eines Containers beheben, der indizierten Zugriff bietet.

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);