You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Dictionary DeepClone() drops the source's key comparer, so a cloned case-insensitive dictionary stops finding keys #77
The HashSet<T> and SortedSet<T> overloads of DeepClone() both keep the source comparer (new(source.Select(DeepClone), source.Comparer)). The dictionary overloads do not:
I verified this against the current main source. It fails in these cases:
A settings or lookup table keyed case-insensitively silently misses lookups after cloning.
If the cloned keys are IDeepCloneable objects that rely on a custom IEqualityComparer, two distinct source keys can collide, or equal ones can split. The clone can then throw ArgumentException: An item with the same key has already been added.
A SortedDictionary input comes back as an unordered Dictionary.
The overloads are also awkward to call. Dictionary<TKey,TValue> implements both IDictionary<,> and IReadOnlyDictionary<,>, so dict.DeepClone() fails to compile with CS0121: the call is ambiguous. The tests work around this with a cast (((IDictionary<string, SimpleObject?>)originalDict).DeepClone()).
Suggested fix
Add a concrete Dictionary<TKey, TValue> DeepClone<TKey, TValue>(this Dictionary<TKey, TValue> source) overload that passes source.Comparer to the new dictionary. Being the most specific match, it also resolves the CS0121 ambiguity for the common case.
In the interface-typed overloads, keep the comparer when the runtime type exposes one (Dictionary<,>, SortedDictionary<,>), and return the same kind of collection where practical.
Acceptance criteria: tests show that a clone of a comparer-bearing dictionary answers lookups the same way as its source, and that dict.DeepClone() compiles on a Dictionary<,> without a cast.
Category: Bug (with a usability Improvement: the CS0121 ambiguity)
Priority: Medium. Cloned case-insensitive or custom-comparer dictionaries silently miss lookups or can throw on key collision, and SortedDictionary loses its ordering. Behavior is incorrect, but it only affects comparer-bearing dictionaries.
Notes: Adding a concrete Dictionary<TKey,TValue> overload resolves both the comparer loss for the common case and the CS0121 ambiguity. Check that it doesn't create new ambiguity for callers that pass SortedDictionary or other IDictionary implementations.
Activity
matt-edmondson commentedon Sep 26, 2026
Triage
SortedDictionaryloses its ordering. Behavior is incorrect, but it only affects comparer-bearing dictionaries.DeepClone()overloadsIReadOnlyDictionary.DeepClone()throwsInvalidCastException), which is in the same overload family.Notes: Adding a concrete
Dictionary<TKey,TValue>overload resolves both the comparer loss for the common case and the CS0121 ambiguity. Check that it doesn't create new ambiguity for callers that passSortedDictionaryor otherIDictionaryimplementations.Generated by Claude Code