zeroc-ice / ice

All-in-one solution for creating networked applications with RPC, pub/sub, server deployment, and more.
https://zeroc.com
GNU General Public License v2.0
2.03k stars 593 forks source link

Dictionary equal and hashing in C# #2126

Closed bernardnormier closed 3 months ago

bernardnormier commented 4 months ago

In C#, we check if two dictionaries are equal using:

https://github.com/zeroc-ice/ice/blob/711bb2939294bb1dbb940e3a4a6966e89c5ed735/csharp/src/Ice/Collections.cs#L103

The algorithm assumes the two dictionaries are sorted in the same order. This is not the behavior you would expect since it depends on the IDictionary implementation. Two implementations with the same contents can easily compare different.

IceRPC C# provides an order-independent implementation of DictionaryEqual: https://github.com/icerpc/icerpc-csharp/blob/57995b702436169798fc3fe5fd513e6f09591397/src/IceRpc/Internal/DictionaryExtensions.cs#L10

Ice C# also provides HashCode computation for these dictionaries that is also order-dependent (that's consistent with Equal, which is good). IceRPC doesn't provide a HashCode implementation. It's not obvious how to provide a correct order-independent HashCode implementation. A simple solution is to hash the size of the dictionary, not its contents.

bernardnormier commented 4 months ago

Another option is to do like Java: the hash code for a Map / Set is the sum of the hash code of all elements: https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Set.html#hashCode()

bernardnormier commented 3 months ago

Fixed: we no longer use "entry hashing" for any dictionary in C#.