diff --git a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentBag.cs b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentBag.cs
index acc0f1f4d8445c..9ee2761b9cd88e 100644
--- a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentBag.cs
+++ b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentBag.cs
@@ -459,7 +459,7 @@ public void Clear()
/// was called. The enumerator is safe to use
/// concurrently with reads from and writes to the bag.
///
- public IEnumerator GetEnumerator() => new Enumerator(ToArray());
+ public IEnumerator GetEnumerator() => ((IEnumerable)ToArray()).GetEnumerator();
///
/// Returns an enumerator that iterates through the Provides an enumerator for the bag.
- ///
- /// The original implementation of ConcurrentBag used a as part of
- /// the GetEnumerator implementation. That list was then changed to be an array, but array's
- /// GetEnumerator has different behavior than does list's, in particular for the case where
- /// Current is used after MoveNext returns false. To avoid any concerns around compatibility,
- /// we use a custom enumerator rather than just returning array's. This enumerator provides
- /// the essential elements of both list's and array's enumerators.
- ///
- private sealed class Enumerator : IEnumerator
- {
- private readonly T[] _array;
- private T? _current;
- private int _index;
-
- public Enumerator(T[] array)
- {
- Debug.Assert(array != null);
- _array = array;
- }
-
- public bool MoveNext()
- {
- if (_index < _array.Length)
- {
- _current = _array[_index++];
- return true;
- }
-
- _index = _array.Length + 1;
- return false;
- }
-
- public T Current => _current!;
-
- object? IEnumerator.Current
- {
- get
- {
- if (_index == 0 || _index == _array.Length + 1)
- {
- throw new InvalidOperationException(SR.ConcurrentBag_Enumerator_EnumerationNotStartedOrAlreadyFinished);
- }
- return Current;
- }
- }
-
- public void Reset()
- {
- _index = 0;
- _current = default;
- }
-
- public void Dispose() { }
- }
}
}
diff --git a/src/libraries/System.Collections.Concurrent/tests/ConcurrentBagTests.cs b/src/libraries/System.Collections.Concurrent/tests/ConcurrentBagTests.cs
index b76b283223aaef..41caa3244f8124 100644
--- a/src/libraries/System.Collections.Concurrent/tests/ConcurrentBagTests.cs
+++ b/src/libraries/System.Collections.Concurrent/tests/ConcurrentBagTests.cs
@@ -11,6 +11,8 @@ namespace System.Collections.Concurrent.Tests
{
public class ConcurrentBagTests : ProducerConsumerCollectionTests
{
+ protected override bool Enumerator_Current_UndefinedOperation_Throws => true;
+ protected override bool Enumerator_Empty_UsesSingletonInstance => true;
protected override IProducerConsumerCollection CreateProducerConsumerCollection() => new ConcurrentBag();
protected override IProducerConsumerCollection CreateProducerConsumerCollection(IEnumerable collection) => new ConcurrentBag(collection);
protected override bool IsEmpty(IProducerConsumerCollection pcc) => ((ConcurrentBag)pcc).IsEmpty;