MongoDB.Bson.Decimal128 doesn't implement GetHashCode correctly

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Unresolved
    • Priority: Major - P3
    • None
    • Affects Version/s: 2.11.5
    • Component/s: BSON
    • None
    • None
    • Hide

      1. What would you like to communicate to the user about this feature?
      2. Would you like the user to see examples of the syntax and/or executable code and its output?
      3. Which versions of the driver/connector does this apply to?

      Show
      1. What would you like to communicate to the user about this feature? 2. Would you like the user to see examples of the syntax and/or executable code and its output? 3. Which versions of the driver/connector does this apply to?
    • None
    • None
    • None
    • None
    • None
    • None

      The GetHashCode implementation of MongoDB.Bson.Decimal128 uses the low and the high bytes to calculate a hashcode. This is problematic, because the standard allows for multiple representations of the same number. For example,
      _high: 6916966077687660544, _low: 10 represents 1.0m
      _high: 1, _low: 0 represents 1

      This is correctly handled in the Equals implementation and `((Decimal128)1.0m).Equals((Decimal128)1)` returns `true`, however `((Decimal128)1.0m).GetHashCode().Equals(((Decimal128)1).GetHashCode())` returns `false`. The most obvious issue that this causes is that a HashSet of Decimal128 values will contain duplicates.

      This is slightly affecting the Realm .NET SDK, which is in the process of adding support for a collection with Set-like semantics. When an object containing such a collection is unmanaged, it uses a HashSet to store the values. Once it gets added to the Realm database, we use a C++ implementation of the collection, which correctly detects 1.0 and 1 as duplicates and only stores one of them. From a user's perspective, it can be surprising that adding an object to the database changes the number of items in the collection.

      Support for `ISet<T>` properties in Realm .NET will ship toward end of January 2021 and it would be nice, but by no means a deal breaker, to have a fix for this issue. We don't expect everyone to suddenly start using sets, and of those, only a small percentage will need to use Decimal128, so I don't imagine we'll start getting swarmed with bug reports.

            Assignee:
            Boris Dogadov
            Reporter:
            Nikola Irinchev
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: