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 or IEnumerator.Reset throws an InvalidOperationException.

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() from SortedDictionary<int, string>: https://dotnetfiddle.net/bssrG7 (throws).