Why does List<T>.ForEach allow its list to be modified?

Solution 1:

It's because the ForEach method doesn't use the enumerator, it loops through the items with a for loop:

public void ForEach(Action<T> action)
{
    if (action == null)
    {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
    }
    for (int i = 0; i < this._size; i++)
    {
        action(this._items[i]);
    }
}

(code obtained with JustDecompile)

Since the enumerator is not used, it never checks if the list has changed, and the end condition of the for loop is never reached because _size is increased at every iteration.

Solution 2:

List<T>.ForEach is implemented through for inside, so it does not use enumerator and it allows to modify the collection.