M.kazem Akhgary
M.kazem Akhgary

Reputation: 19149

does foreach loop handle Changes in list length correctly?

does foreach correctly iterate over flexible list?

for example

//will iterate over all items in list?
foreach (var obj in list)
{
    //list length changes here
    //ex:

    list.Add(...);
    list.Remove(...);
    list.Concat(...);
    // and so on
}

and if it does ...how?

Upvotes: 1

Views: 2129

Answers (4)

Antaryami Swain
Antaryami Swain

Reputation: 31

You cannot change the collection inside the for each loop of the same collection. if you want you can use for loop to change the collection length.

Upvotes: 3

Akshay Soam
Akshay Soam

Reputation: 1620

You can't modify a collection while enumerating it inside a foreach statement.

You should use another pattern to do what you are trying to do because the for each does not allow you to change the enumerator you are looping to.

For Example: Imagine if you run a foreach on a sorted list from the beginning, you start processing item with key="A" then you go to "B" then you change "C" to "B", what's going to happen? Your list is resorted and you don't know anymore what you are looping and where you are.

In general you "could" do it with a for(int i=dictionary.count-1; i>=0; --i) or something like that but this also depends on your context, I would really try to use another approach.

Internal Working: IEnumerator<t> is designed to enable the iterator pattern for iterating over collections of elements, rather than the length-index. IEnumerator<t> includes two members.

  • The first is bool MoveNext(). Using this method, we can move from one element within the collection to the next while at the same time detecting when we have enumerated through every item using the Boolean return.

  • The second member, a read-only property called Current, returns the element currently in process. With these two members on the collection class, it is possible to iterate over the collection simply using a while loop.

The MoveNext() method in this listing returns false when it moves past the end of the collection. This replaces the need to count elements while looping. (The last member on IEnumerator<t> , Reset(), will reset the enumeration.)

Upvotes: 3

Saagar Elias Jacky
Saagar Elias Jacky

Reputation: 2688

The collection you use in a foreach loop is immutable. As per MSDN

The foreach statement is used to iterate through the collection to get the information that you want, but can not be used to add or remove items from the source collection to avoid unpredictable side effects. If you need to add or remove items from the source collection, use a for loop.

But as per this link, it looks like this is now possible from .Net 4.0

Upvotes: 2

jmoreno
jmoreno

Reputation: 13561

Per the documentation, if changes are made inside the loop the behavior is undefined. Undefined means that there are no restrictions on what it can do, there is no "incorrect behavior" when the behavior is undefined...crash, do what you want, send an email to your boss calling him nasty names and quiting, all equally valid. I would hope for a crash in this case, but again, whatever happens, happens and is considered "correct" according to the documentation.

Upvotes: 3

Related Questions