# Why does this Unity code work as expected only with the while loop?

In unity, in C#, I have the following code in Awake():

Awake()
{
Transform obj = InstantiateTarget();
//the bizarrely required and "working" loop
while (transform.childCount > 0)
{
//assign all current children to the replacement object
foreach (Transform t in transform)
{
t.parent = obj;
}
}

Destroy(gameObject);
}


Without the while loop, some random set of the transforms children are destroyed by that end Destroy. With the while, it works exactly as expected (all transform's children become obj's children).

Also, surely with it, there should be an infinite loop (if nothing is changing in another thread, as implied by unity docs). This is in Unity 3.5.

Why does it only work with the while loop? And why doesn't unity get stuck in an infinite loop?

• "With the while, it works exactly as expected." - Which is? What is the expected output? – user15805 Mar 28 '13 at 14:58
• The expected output: parent all children to obj. The output without the while loop: only some children are parented to obj, some remain parented to transform – Matt Bond Mar 28 '13 at 15:00
• You're getting good answers here, though I believe this belongs on stackoverflow. – MichaelHouse Mar 28 '13 at 16:29
• Technically, if Unity did not suppress the thrown exception, you would've noticed the issue right away. The answer requires knowledge of this (Unity) bug so, in my opinion, this is the place for the question. – user15805 Mar 28 '13 at 17:11
• You're iterating over a collection while removing elements from it (which is what changing its parent will do). This is illegal and produces undefined behavior (or oddness like only iterating over a subset of all items in the collection) for most data structures in almost all languages. This is a basic programming question, nothing super specific to games, C#, or Unity. – Sean Middleditch Mar 30 '13 at 2:59

It's actually Unity's fault for being quite confusing here. You are not allowed to alter a collection that you're enumerating with a foreach loop. Suppose this:

List<string> SomeList = new List<string>();
foreach (string s in SomeList)
{
SomeList.Remove(s); //WRONG! You cannot alter the collection here. Use a for loop instead!
}


Normally, this is not allowed in Mono and throws an exception. Unity apparently suppresses it and tells you nothing. Here's what actually happens in your code:

Awake()
{
Transform obj = InstantiateTarget();
//While there are no children attached to this transform;
while (transform.childCount > 0) /*Not an infinite loop
because on each step you're removing
a child from this transform
{
//Try to attach each child to obj
foreach (Transform t in transform)
{
t.parent = obj; /*The first "t" gets attached, but you're also
altering the collection (this.transform loses track of t).
The foreach loop stops completely!
Since you're executing the foreach loop for
as long as this.transfom has children, you
essentially remove one child transform at a time on
each 'while' pass.*/
}
}
Destroy(gameObject);
}


Use a for loop instead and, as a rule of thumb, every time you write a foreach loop, ask yourself if you're not actually trying to remove items from the collection. If you are, stop right there and use the for loop instead.

• C#'s foreach behavior in a nutshell, good catch (pun) on Unity subverting the exception and pretending nothing happened. – Patrick Hughes Mar 28 '13 at 15:46
• Argh, of course! I didn't even think that I was modifying a collection, as I was changing the parent of a member of it. Of course it makes sense that it immediately affect transform, I just didn't connect the dots far enough! Thanks for the enlightenment! – Matt Bond Mar 28 '13 at 16:34