6

Can I safely add nodes to LinkedList container inside foreach statement? Is there any difference if I used while loop? Or it is never allowed and can cause some problems?

foreach(var node in myList)
{
    if(condition)
        myList.AddLast(new MyNode());
}

Will it always work?

4 Answers 4

8

You can't modify a collection while you're enumerating over it.

From the docs for LinkedList<T>.GetEnumerator:

An enumerator remains valid as long as the collection remains unchanged. If changes are made to the collection, such as adding, modifying, or deleting elements, the enumerator is irrecoverably invalidated and its behavior is undefined.

In practice I believe it will always throw an InvalidOperationException, despite the behaviour officially being undefined.

EDIT: You asked in a comment whether a while loop would help... a while loop using GetEnumerator/MoveNext/Current wouldn't, but this will:

LinkedListNode<MyNode> current = myList.First;
while (current != null)
{
    if (condition) // use current.Value to get the value
    {
        myList.AddLast(new MyNode());
    }
    current = current.Next;
}

As far as I'm aware, that's entirely safe and predictable. You can always ask a node for its next node. If you happen to be looking at the tail node and add another one, you'll get the new tail node when you ask for "next".

If that doesn't help, please give us more details about what you're trying to achieve.

Sign up to request clarification or add additional context in comments.

1 Comment

Entirely safe is a stretch, endless loop and OOM if the new node matches the condition.
2

No, enumerator object remembers internal version of owning collection. After collection is modified - version changed, so foreach will fail.

1 Comment

+1 For peeking in with reflector to see how the enumerators were implementing the check :)
1

While iterating over a collection with the foreach statement, you cannot modify it. Thus, adding items will result in a compiler error.

3 Comments

You can use a while loop to loop over the collection. You will not receive a compiler error when doing this, but be careful not to write an infinite loop - which can happen if new MyNode() fulfills condition.
It won't result in a compiler error. The code given will compile with no problem. It will throw an exception at execution time.
@Jon Skeet: Oops - I just remembered Visual Studio complain about this code and thought it would be a compiler error ... Thanks!
0

Perhaps you could add them to a new list. Then at the end, outside the foreach use .addrange() to append the new ones to the original list.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.