编辑(结论。最终。结束。):这是一个错误。
请参阅包含 double.NaN 的列表中 List<double/single>.Sort() [.NET35] 中的错误报告错误,并在为什么 .NET 4.0 对这个数组的排序不同于 .NET 3.5?我从中撕掉了链接。
历史沉思
[参见帖子:为什么 .NET 4.0 对这个数组的排序与 .NET 3.5 不同?,希望能真正找到关于这个特定问题的更有用的讨论。我也在那里交叉发布了这个回复。]
Phil 在 .NET4 中指出的行为是在 CompareTo 中定义的。请参阅.NET4的 double.CompareTo。这与 .NET35 中的行为相同,但是根据方法文档,两个版本中应该保持一致...
Array.Sort(double[])
:似乎没有CompareTo(double[])
按预期使用,这很可能是一个错误——请注意下面 Array.Sort(object[]) 和 Array.Sort(double[]) 的区别。我希望对以下内容进行澄清/更正。
无论如何,使用>
and的答案<
和==
解释为什么这些运算符不起作用但未能解释为什么Array.Sort
会导致意外输出。以下是我的一些发现,尽管它们可能微不足道。
首先,double.CompareTo(T)
方法文档——这个顺序是根据文档明确定义的:
小于零:此实例小于值。- 或 - 此实例不是数字 (NaN),值是数字。
零:此实例等于值。- 或 - 此实例和值都不是数字 (NaN)、PositiveInfinity 或 NegativeInfinity。
大于零:此实例大于值。- 或 - 此实例是一个数字,而值不是一个数字 (NaN)。
在 LINQPad(3.5 和 4,两者都有相同的结果):
0d.CompareTo(0d).Dump(); // 0
double.NaN.CompareTo(0d).Dump(); // -1
double.NaN.CompareTo(double.NaN).Dump(); // 0
0d.CompareTo(double.NaN).Dump(); // 1
使用CompareTo(object)
具有相同的结果:
0d.CompareTo((object)0d).Dump(); // 0
double.NaN.CompareTo((object)0d).Dump(); // -1
double.NaN.CompareTo((object)double.NaN).Dump(); // 0
0d.CompareTo((object)double.NaN).Dump(); // 1
所以这不是问题。
现在,从Array.Sort(object[])
文档中 - 没有使用>
,<
或==
(根据文档) - 只是CompareTo(object)
.
IComparable
使用 Array的每个元素的实现对整个一维 Array 中的元素进行排序。
同样,Array.Sort(T[])
使用CompareTo(T)
.
使用 Array 的每个元素的 IComparable(Of T) 通用接口实现对整个 Array 中的元素进行排序。
让我们来看看:
LINQPad (4):
var ar = new double[] {double.NaN, 0, 1, double.NaN};
Array.Sort(ar);
ar.Dump();
// NaN, NaN, 0, 1
LINQPad(3.5):
var ar = new double[] {double.NaN, 0, 1, double.NaN};
Array.Sort(ar);
ar.Dump();
// NaN, 0, NaN, 1
LINQPad (3.5) --注意数组是对象CompareTo
,并且行为是根据合同“预期的” 。
var ar = new object[] {double.NaN, 0d, 1d, double.NaN};
Array.Sort(ar);
ar.Dump();
// NaN, NaN, 0, 1
唔。真的。综上所述:
我不知道。
快乐编码。