Переопределить 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 появляется поверх списка при сортировке, что является самым популярным поведением.