Ответ 1
Изменить (окончание. окончание.): Это ошибка.
См. отчет об ошибке Ошибка в списке < double/single > .Sort() [.NET35] в списке, который содержит double.NaN и пойдите, дайте Хансу Пассану голосование на Почему .NET 4.0 сортирует этот массив по-другому, чем .NET 3.5?, из которого я разорвал ссылку.
Исторические размышления
[См. сообщение: Почему .NET 4.0 сортирует этот массив по-другому, чем .NET 3.5?, где, надеюсь, более полезное обсуждение этой конкретной проблемы может быть выдумал для реального. Я также разместил здесь этот ответ.]
Поведение, указанное в .NET4 от Phil, указано в CompareTo. См. double.CompareTo для .NET4. Это то же поведение, что и в .NET35, но должно быть согласованным в обеих версиях, по документации метода...
Array.Sort(double[])
: кажется, не использует CompareTo(double[])
, как ожидалось, и это может быть очень ошибкой - обратите внимание на разницу в Array.Sort(object []) и Array.Sort(double []) ниже. Мне хотелось бы уточнить/исправить следующее:
В любом случае ответы с использованием >
и <
и ==
объясняют, почему эти операторы не работают, но не могут объяснить, почему 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.Sort(T[])
использует CompareTo(T)
.
Сортирует элементы во всем массиве, используя реализацию универсального интерфейса IComparable (Of T) каждого элемента массива.
Посмотрим:
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
Хм. В самом деле. В заключение:
У меня нет ИДЕИ.
Счастливое кодирование.