views:

253

answers:

3

Imagine that during a

foreach(var item in enumerable)

The enumerable items change. It will affect the current foreach?

Example:

var enumerable = new List<int>();
enumerable.Add(1);
Parallel.ForEach<int>(enumerable, item =>
{ 
     enumerable.Add(item + 1);
});

It will loop forever?

+1  A: 

This fully depends on how IEnumerable is implemented.

With a List, It will throw an IllegalOperationException. But don't rely on this behaviour for IEnumarables. Some loop endless and will throw an OutOfMemoryexception quickly.

Dykam
Dykam: Nope. It'll fail immediately.
Mehrdad Afshari
I edited. Learned another thing.
Dykam
+5  A: 

Depends on the nature of the enumerator. Many of them throw exception when the collection changes.

For instance, List<T> throws an InvalidOperationException if the collection changes during enumeration.

Mehrdad Afshari
+6  A: 

Generally, it should throw an exception. The List<T> implementation of GetEnumerator() Provides an Enumerator<T> object whose MoveNext() method looks like this (from Reflector):

public bool MoveNext()
{
    List<T> list = this.list;
    if ((this.version == list._version) && (this.index < list._size))
    {
        this.current = list._items[this.index];
        this.index++;
        return true;
    }
    return this.MoveNextRare();
}


private bool MoveNextRare()
{
    if (this.version != this.list._version)
    {
        ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
    }
    this.index = this.list._size + 1;
    this.current = default(T);
    return false;
}

The list._version is modified (incremented) on each operation which modifies the List.

kek444