Почему Convert.ToString (null) возвращает другое значение, если вы используете null?


116
Convert.ToString(null)

возвращается

null

Как я и предполагал.

Но

Convert.ToString(null as object)

возвращается

""

Почему они разные?

Ответы:


143

Здесь ToStringв игру вступают 2 перегрузки

Convert.ToString(object o);
Convert.ToString(string s);

Компилятор C # по существу пытается выбрать наиболее конкретную перегрузку, которая будет работать с вводом. nullЗначение конвертируемые в любой ссылочного типа. В этом случае stringболее конкретно, objectи, следовательно, он будет выбран победителем.

В null as objectвы закрепили тип выражения как object. Это означает, что он больше не совместим с stringперегрузкой, и компилятор выбирает objectперегрузку, поскольку она остается единственной совместимой.

По-настоящему непростые подробности того, как работает эта проблема, рассмотрены в разделе 7.4.3 спецификации языка C #.


15
Хорошо. Таким образом, он использует одну перегрузку вместо другой. Имеет смысл. Но разве обе перегрузки не должны возвращать одно и то же? +1 кстати.
— Джон Макинтайр

2
@JohnMacIntyre - Это зависит от команды разработчиков, а не от компилятора.
— JonH

8
@JohnMacIntyre Если вы посмотрите на реализацию, Convert.ToString(string)это просто функция идентификации, хотя на Convert.ToString(object)самом деле пройти путь труднее. На первый взгляд, я бы согласился, что они должны вернуть то же самое, но конвертируемый слой BCL - это не то, в чем я очень разбираюсь, и, возможно, есть веская причина для разницы (хотя я скептически настроен)
— JaredPar

Я пришел сюда, чтобы узнать, как преобразовать нулевой объект в нулевую строку. Ответ для других поисковиков: (string)nullили, если ваш объект называется o, то(string)o
— rayzinnz

65

Следуя отличному ответу JaredPar по разрешению перегрузки, остается вопрос: «Почему Convert.ToString(string)возвращается null, но Convert.ToString(object)возвращается string.Empty»?

И ответ на это ... потому что так сказано в документации :

Convert.ToString (string) возвращает «указанный экземпляр строки; фактическое преобразование не выполняется».

Convert.ToString (объект) возвращает «строковое представление значения или String.Empty, если значение равно нулю».

РЕДАКТИРОВАТЬ: Что касается того, является ли это «ошибкой в ​​спецификации», «очень плохим дизайном API», «почему он был указан таким образом» и т. Д. - я попытаюсь объяснить, почему я не вижу это как большое дело.

  1. System.Convertимеет методы для преобразования каждого базового типа в себя . Это странно - поскольку преобразование не требуется или невозможно, поэтому методы в конечном итоге просто возвращают параметр. Convert.ToString(string)ведет себя так же. Я предполагаю, что это здесь для сценариев генерации кода.
  2. Convert.ToString(object)после прохождения имеет 3 варианта ответа null. Бросить, вернуть null или вернуть строку. Пусто. Бросать было бы плохо - вдвойне, если предположить, что они используются для сгенерированного кода. Возврат null требует, чтобы ваш вызывающий объект выполнил проверку на null - опять же, не лучший выбор для сгенерированного кода. Возврат string.Empty кажется разумным выбором. Остальное System.Convertкасается типов значений, которые имеют значение по умолчанию.
  3. Спорный вопрос, является ли возврат null более «правильным», но string.Empty определенно более удобен. Изменение Convert.ToString(string)означает нарушение правила «без фактического преобразования». Поскольку System.Convertэто статический служебный класс, каждый метод логически можно рассматривать как собственный. В реальном мире очень мало сценариев, в которых такое поведение должно быть «неожиданным», так что пусть удобство использования преобладает над (возможной) правильностью.

Можно ли сказать, что это ошибка в спецификации?
— Джон Макинтайр

3
это не объясняет, почему это так. Сказать, что он ведет себя так, потому что он задокументирован, чтобы вести себя так, - тавтологично.
— CodesInChaos

2
@JohnMacIntyre ИМО, справедливо сказать, что это очень плохой дизайн API.
— CodesInChaos

7
@CodeInChaos - это не тавтология, если вы не предполагаете, что документы написаны на основе наблюдаемого поведения после разработки BCL. Думаю, это было бы странное предположение. IOW, это не «задокументировано, чтобы вести себя подобным образом», это «задокументировано, что оно будет вести себя так», то есть « указано, чтобы вести себя подобным образом».
— Марк Брэкетт

8
Это только смещает вопрос «почему было указано, что он должен вести себя так?»
— CodesInChaos,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.