Dictionary methods Remove and Clear (.NET Core) modify the collection during enumeration. No exception thrown
This appears to be an intentional difference between .Net full framework and .Net core for Dictionary<TKey, TValue>
.
The divergence occurred in Pull #18854: Remove version increment from Dictionary.Remove overloads:
Removes the version increment from Remove operations
This addresses the coreclr side of the api change Add Dictionary.Remove(predicate) with the intention of allowing removal of items from the dictionary while enumerating per direction from @jkotas . All collections tests and modified and new tests added in the related corefx PR.
There appears to be an open documentation issue:
Issue #42123: Clarify Dictionary behavior/guarantees around mutation during enumeration:
Is it correct to say that the current implementation of Dictionary supports non-concurrent mutation during iteration?
Only removal. This was enabled as a feature in dotnet/coreclr#18854.
is this something that can be depended on going forward
Yes.
We should ensure the docs are updated to reflect this.
You might want to add a vote to the open doc issue requesting clarification as the .Net core 3.0 documentation for Dictionary<TKey,TValue>.GetEnumerator()
is now obsolete:
If changes are made to the collection, such as adding, modifying, or deleting elements, the enumerator is irrecoverably invalidated and the next call to
MoveNext
orIEnumerator.Reset
throws anInvalidOperationException
.
Strangely enough, the enumerator for SortedDictionary<TKey, TValue>
does throw when the dictionary is modified during enumeration.
Demos:
- .Net framework
Remove()
: https://dotnetfiddle.net/8vONOw (throws). - .Net core
Remove()
: https://dotnetfiddle.net/es6STm (does not throw). - .Net core
Add()
: https://dotnetfiddle.net/6q7Lvx (throws). - .Net core
Remove()
fromSortedDictionary<int, string>
: https://dotnetfiddle.net/bssrG7 (throws).