Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix FrozenDictionary/Set handling of ValueTuple keys #84280

Merged
merged 1 commit into from
Apr 4, 2023

Conversation

stephentoub
Copy link
Member

For small collections of comparable value types, we were using an implementation that sorted the keys in order to a) quickly rule out values outside of the known contained range, and b) stop searching when we hit a value that was too small. However, this can break for some well-known types. In particular, ValueTuple<...> implements IComparable<ValueTuple<...>>, but it might throw an exception if you actually try to use its IComparable<> implementation if any of the T types in the tuple are themselves not comparable. Since we have no good way then to dynamically select an implementation based on whether it implements IComparable<>, I've simply removed those checks / calls from the implementation.

Testing this also highlighted that our existing shared set tests don't like being given non-comparable types, as they use SortedSet which itself suffers from effectively the same issue (but there you can choose to not use SortedSet if it doesn't work for your data, and "sort"ing is part of the name).

For small collections of comparable value types, we were using an implementation that sorted the keys in order to a) quickly rule out values outside of the known contained range, and b) stop searching when we hit a value that was too small.  However, this can break for some well-known types. In particular, `ValueTuple<...>` implements `IComparable<ValueTuple<...>>`, but it might throw an exception if you actually try to use its `IComparable<>` implementation if any of the `T` types in the tuple are themselves not comparable.  Since we have no good way then to dynamically select an implementation based on whether it implements `IComparable<>`, I've simply removed those checks / calls from the implementation.

Testing this also highlighted that our existing shared set tests don't like being given non-comparable types, as they use SortedSet which itself suffers from effectively the same issue (but there you can choose to not use SortedSet if it doesn't work for your data, and "sort"ing is part of the name).
@ghost
Copy link

ghost commented Apr 4, 2023

Tagging subscribers to this area: @dotnet/area-system-collections
See info in area-owners.md if you want to be subscribed.

Issue Details

For small collections of comparable value types, we were using an implementation that sorted the keys in order to a) quickly rule out values outside of the known contained range, and b) stop searching when we hit a value that was too small. However, this can break for some well-known types. In particular, ValueTuple<...> implements IComparable<ValueTuple<...>>, but it might throw an exception if you actually try to use its IComparable<> implementation if any of the T types in the tuple are themselves not comparable. Since we have no good way then to dynamically select an implementation based on whether it implements IComparable<>, I've simply removed those checks / calls from the implementation.

Testing this also highlighted that our existing shared set tests don't like being given non-comparable types, as they use SortedSet which itself suffers from effectively the same issue (but there you can choose to not use SortedSet if it doesn't work for your data, and "sort"ing is part of the name).

Author: stephentoub
Assignees: stephentoub
Labels:

area-System.Collections

Milestone: -

@stephentoub
Copy link
Member Author

Once this is back in a known-good state, I'll subsequently look at adding back a comparable-based implementation used for an allow-list of types we know to be acceptable, e.g. primitives.

@stephentoub stephentoub merged commit e579ccb into dotnet:main Apr 4, 2023
@stephentoub stephentoub deleted the frozentuple branch April 4, 2023 11:21
@ghost ghost locked as resolved and limited conversation to collaborators May 4, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants