为什么.NET 4.0对此数组的排序与.NET 3.5不同?

Phi*_*hil 44 .net c#

这个stackoverflow问题提出了一个关于使用NaN值对双数组进行排序的有趣问题.OP发布了以下代码:

static void Main(string[] args)
{
    double[] someArray = { 4.0, 2.0, double.NaN, 1.0, 5.0, 3.0, double.NaN, 10.0, 9.0, 8.0 };

    foreach (double db in someArray)
    {
        Console.WriteLine(db);
    }

    Array.Sort(someArray);
    Console.WriteLine("\n\n");
    foreach (double db in someArray)
    {
        Console.WriteLine(db);
    }

    Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)

在.NET 3.5框架下运行时,数组按如下方式排序:

1,4,NaN,2,3,5,8,9,10,NaN

当您在.NET 4.0下运行它时,数组的逻辑排序更为一些:

NaN,NaN,1,2,3,4,5,8,9,10

我可以理解为什么它会在.NET 3.5中奇怪地排序(因为NaN不等于,小于或大于任何东西).我也可以理解为什么它会像在.NET 4.0中那样排序.我的问题是,为什么这个从3.5变为4.0?这个变化的Microsoft文档在哪里?

Han*_*ant 38

这是一个bug修复.带有错误详细信息的反馈报告就在这里.微软对错误报告的回应:

请注意,此错误会影响以下内容:

  • Array.Sort(),其中数组包含Double.NaN
  • Array.Sort(),其中数组包含Single.NaN
  • 任何上面的调用者,例如在List.Sort()上,其中list包含Double.NaN

此错误将在运行时的下一个主要版本中修复; 在此之前,您可以使用执行正确排序的自定义IComparer来解决此问题.正如变通方法注释中所提到的,不要使用Comparer.Default,因为这是特殊情况下的快捷排序例程,无法正确处理NaN.相反,您可以提供自己的比较器,提供相同的比较,但不会是特殊的比较.


Tho*_*que 6

不是一个真正的答案,但也许是一个线索......您可以使用以下代码重现4.0中奇怪的3.5行为:

void Main()
{
    double[] someArray = { 4.0, 2.0, double.NaN, 1.0, 5.0, 3.0, double.NaN, 10.0, 9.0, 8.0 };
    Array.Sort(someArray, CompareDouble);
    someArray.Dump();
}

int CompareDouble(double a, double b)
{
    if (a > b)
        return 1;
    if (a < b)
        return -1;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在这里,无论是a > ba < b返回false,如果A或B NaN,所以CompareDouble方法返回0,所以NaN被认为是等于一切......这给了相同的结果3.5:

1,4,NaN,2,3,5,8,9,10,NaN
Run Code Online (Sandbox Code Playgroud)