为什么微软要的不是固定的Equals和GetHashCode与南错误的实现? [关闭](Why

2019-08-06 11:55发布

在.NET Framework中,实现( override的) Equals(object)GetHashCode()用于浮点类型( System.DoubleSystem.Single )是错误的 。 从引用MSDN GetHashCode(object)规范 :

哈希函数必须具有以下特性:

•如果两个对象的比较结果为相等,为每个对象GetHashCode方法必须返回相同的值。 但是,如果两个对象不比较结果相等,两个对象的GetHashCode方法不必返回不同的值。

如果你拍二NaN值不同的二进制表示,这两个对象都比较之下平等Equals方法,但是哈希码(几乎总是)是不同的。

现在,已经这个错误被报道微软连接。 但是,为什么他们会不解决这一问题?

解决方法是简单的:要么让不同NaN 并不等同,或者选择一个固定的散列码返回任何NaN

此修复程序不会打破任何东西:今天的事情的方式,在不同的实在不行NaN使用。

你能想到的任何理由不解决这一问题?

下面是说明当前的行为一个简单的例子:

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);
  }
}

在一次百万重复:运行的代码的结果HashSet<>

请注意:这有什么没有做的==!= C#的运营商。 请使用Equals如果你想检查自己这一点。

文章来源: Why would Microsoft want NOT to fix the wrong implementations of Equals and GetHashCode with NaN? [closed]