diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs index 1df1ea89696c5f..8eb0e5e9b7a2d2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs @@ -666,7 +666,7 @@ public void ForEach(Action action) IEnumerator IEnumerable.GetEnumerator() => Count == 0 ? SZGenericArrayEnumerator.Empty : - GetEnumerator(); + new EnumeratorObject(this); IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)this).GetEnumerator(); @@ -1251,5 +1251,72 @@ void IEnumerator.Reset() _current = default; } } + + private sealed class EnumeratorObject : IEnumerator, IEnumerator + { + private readonly List _list; + private int _index; + private readonly int _version; + private T? _current; + + internal EnumeratorObject(List list) + { + _list = list; + _index = 0; + _version = list._version; + _current = default; + } + + void IDisposable.Dispose() + { + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool MoveNext() + { + List localList = _list; + + if (_version != localList._version) + { + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion(); + } + + if ((uint)_index < (uint)localList._size) + { + _current = localList._items[_index]; + _index++; + return true; + } + + _current = default; + _index = localList._size + 1; + return false; + } + + public T Current => _current!; + + object? IEnumerator.Current + { + get + { + if (_index == 0 || _index == _list._size + 1) + { + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen(); + } + return Current; + } + } + + void IEnumerator.Reset() + { + if (_version != _list._version) + { + ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion(); + } + + _index = 0; + _current = default; + } + } } }