Dlaczego Microsoft chciałby NIE naprawiać błędnych implementacji Equals i GetHashCode za pomocą NaN? [Zamknięte]

W systemie .NET Framework implementacja (override) zEquals(object) iGetHashCode() dla typów zmiennoprzecinkowych (System.Double iSystem.Single) jestźle. Cytować zMSDNGetHashCode(object) specyfikacja:

Funkcja skrótu musi mieć następujące właściwości:

• Jeśli dwa obiekty są porównywane jako równe, metoda GetHashCode dla każdego obiektu musi zwrócić tę samą wartość. Jeśli jednak dwa obiekty nie będą porównywane jako równe, metody GetHashCode dla dwóch obiektów nie muszą zwracać różnych wartości.

Jeśli weźmiesz dwaNaN wartości z różnymi reprezentacjami binarnymi, oba obiekty porównują się równe podEquals metoda, ale kody skrótu są (prawie zawsze) różne.

Teraz ten błąd mazgłoszono na Microsoft Connect.Ale dlaczego nie naprawią tego?

Poprawka jest łatwa: albo niech innaNaN nie porównaj jako równe lub wybierz stały kod skrótu, aby wrócić za dowolnyNaN.

Poprawka nie złamie niczego: sposób, w jaki rzeczy są dzisiaj, nic nie działa, gdy jest inaczejNaN są używane.

Czy możesz pomyśleć okażdy powód, aby tego nie naprawić?

Oto prosty przykład ilustrujący obecne zachowanie:

using System;
using System.Collections.Generic;
using System.Linq;

static class Program
{
  const int setSize = 1000000; // change to higher value if you want to waste even more memory
  const double oneNaNToRuleThemAll = double.NaN;
  static readonly Random randomNumberGenerator = new Random();

  static void Main()
  {
    var set = new HashSet<double>();   // uses default EqualityComparer<double>

    while (set.Count < setSize)
      set.Add(GetSomeNaN());

    Console.WriteLine("We now have a set with {0:N0} members", set.Count);
    bool areAllEqualToTheSame = set.All(oneNaNToRuleThemAll.Equals);
    if (areAllEqualToTheSame)
      Console.WriteLine("By transitivity, all members of the set are (pairwise) equal.");
  }

  static double GetSomeNaN()  // can also give PositiveInfinity, NegativeInfinity (unlikely)
  {
    byte[] b = new byte[8];
    randomNumberGenerator.NextBytes(b);
    b[7] |= 0x7F;
    b[6] |= 0xF0;
    return BitConverter.ToDouble(b, 0);
  }
}

Wynik uruchomienia kodu: milion duplikatów wHashSet<>.

UWAGA: To manic w ogóle zrobić z== i!= operatory C #. Proszę użyćEquals jeśli chcesz to sprawdzić sam.

questionAnswers(0)

yourAnswerToTheQuestion