Переопределить CompareTo: что делать с нулевым случаем?

что должно быть возвращено в CompareTo метод, когда данный объект null?

на библиотека MSDN показывает пример, где 1 возвращается. Но я ожидал бы бросить ошибку, потому что по сравнению с null не возможно.

Я ожидаю, что разные мнения на этот ответ. Какой подход может быть наилучшим?

4 ответов


Да, есть лучшая практика. Вопреки тому, что говорят другие ответы, существует ожидаемый стандарт, а не просто самое популярное поведение.

правильный ответ приведен в документации MSDN для IComparable<T>.CompareTo и IComparable.CompareTo:

по определению, любой объект, сравнивает больше, чем null и два null ссылки считаются равными друг другой.

(по контракту сравнение большего определяется как: if a > b затем a.CompareTo(b) > 0.)

это ожидаемое поведение также подтверждается, например, в Nullable.Compare<T>. Null всегда сравнивается как меньше значения.

также стоит отметить, что для неродового сравнения несоответствующие типы не должны рассматриваться как null:

параметра параметр obj, должен иметь тот же тип, что и класс или значение тип который реализует этот интерфейс, в противном случае-исключение ArgumentException заброшенный.


это не влияет на ваш вопрос, но имейте в виду, Nullable<T> comparison operators (==, !=, <, <=, >, >=) не следуют IComparable.

при выполнении сравнений с типами с нулевым значением, если значение одного из типов nullable является null, а другой-нет, все сравнения оценить до false за исключением != (Не равно). Важно не предположим, что, поскольку определенное сравнение возвращает false, в противоположный случай возвращает true. В следующем примере, 10 не больше, меньше или равно нулю. Только num1 != num2 значение true.

существует также нечетный результат, что (int?)null == (int?)null возвращает true, но (int?)null <= (int?)null нет.


выбор за вами. Это не выходит за рамки возможности представить действительный случай использования, когда я сравниваю что-то с ничем и хочу, чтобы "что-то" рассматривалось как большее. Но именно поэтому вы переопределяете его, чтобы вы могли решить, как вы хотите справиться с этим делом.


лучшие практики будет зависеть от вашего конкретного случая: по сравнению с null может быть возможно в зависимости от объекта вы сравниваете.

Если я определяю свой объект так, что null является наименьшим возможным значением для любого сравнения, а затем по сравнению с null явно возможно и имеет четко определенный результат. В других случаях исключение может иметь больше смысла.

В конечном счете, это (довольно субъективный) вопрос дизайна, к которому нет обязательно один ответ.


CompareTo с нулевым аргументом влияет на случай при сортировке списка с нулевыми элементами. Возвращая 1, когда данный объект равен null, null появляется поверх списка при сортировке, что является самым популярным поведением.