Por que Convert.ToString (null) retorna um valor diferente se você converter null?


116
Convert.ToString(null)

retorna

null

Como eu esperava.

Mas

Convert.ToString(null as object)

retorna

""

Por que são diferentes?

Respostas:


143

Existem 2 sobrecargas ToStringque entram em jogo aqui

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

O compilador C # tenta essencialmente escolher a sobrecarga mais específica que funcionará com a entrada. Um nullvalor pode ser convertido em qualquer tipo de referência. Neste caso, stringé mais específico do que objecte, portanto, será escolhido como o vencedor.

No null as objectvocê solidificou o tipo da expressão como object. Isso significa que ele não é mais compatível com a stringsobrecarga e o compilador escolhe a objectsobrecarga, pois é o único compatível restante.

Os detalhes realmente complicados de como essa quebra de empate funciona são abordados na seção 7.4.3 das especificações da linguagem C #.


15
Está bem. Portanto, está usando uma sobrecarga em vez da outra. Faz sentido. Mas as duas sobrecargas não deveriam retornar a mesma coisa? +1 btw.
John MacIntyre

2
@JohnMacIntyre - Isso depende da equipe de desenvolvimento, não do compilador.
JonH

8
@JohnMacIntyre Se você olhar para a implementação Convert.ToString(string)dela, é apenas uma função de identidade enquanto, Convert.ToString(object)na verdade, segue um caminho mais difícil de seguir. À primeira vista, eu concordaria que eles deveriam retornar o mesmo, mas a camada conversível do BCL não é algo que eu tenho muito conhecimento e é possível que haja uma boa razão para a diferença (embora eu seja cético)
JaredPar

Vim aqui procurando como converter um objeto nulo em uma string nula. A resposta para outros pesquisadores é (string)null, ou se você (string)o
contestar

65

Seguindo a excelente resposta de resolução de sobrecarga de JaredPar - a pergunta permanece "por que Convert.ToString(string)retorna nulo, mas Convert.ToString(object)retorna string.Empty"?

E a resposta para isso é ... porque os docs dizem assim :

Convert.ToString (string) retorna "a instância de string especificada; nenhuma conversão real é realizada."

Convert.ToString (object) retorna "a representação de string do valor, ou String.Empty se o valor for nulo."

EDITAR: sobre se isso é um "bug na especificação", "design de API muito ruim", "por que foi especificado assim", etc. - Vou tentar explicar por que não vejo é tão grande coisa.

  1. System.Convertpossui métodos para converter cada tipo de base em si mesmo . Isso é estranho - já que nenhuma conversão é necessária ou possível, então os métodos acabam retornando apenas o parâmetro. Convert.ToString(string)se comporta da mesma forma. Presumo que estejam aqui para cenários de geração de código.
  2. Convert.ToString(object)tem 3 opções quando aprovado null. Lançar, retornar nulo ou retornar string.Empty. Jogar seria ruim - duplamente com a suposição de que são usados ​​para código gerado. Retornar nulo exige que seu chamador faça uma verificação de nulo - novamente, não é uma ótima escolha no código gerado. Retornar string.Empty parece uma escolha razoável. O resto System.Convertlida com tipos de valor - que têm um valor padrão.
  3. É discutível se retornar null é mais "correto", mas string.Empty é definitivamente mais utilizável. Mudar Convert.ToString(string)significa quebrar a regra de "nenhuma conversão real". Como System.Converté uma classe de utilitário estático, cada método pode ser tratado logicamente como seu. Existem muito poucos cenários do mundo real onde esse comportamento deveria ser "surpreendente", então deixe a usabilidade vencer a (possível) correção.

É justo dizer que isso é um bug na especificação?
John MacIntyre

3
isso não responde por que é assim. Dizer que se comporta assim porque está documentado é tautológico.
CodesInChaos

2
@JohnMacIntyre IMO, é justo dizer que é um projeto de API muito ruim.
CodesInChaos

7
@CodeInChaos - não é uma tautologia, a menos que você assuma que os documentos foram escritos com base no comportamento observável depois que o BCL foi desenvolvido. Seria uma suposição estranha, eu acho. IOW, não é "documentado para se comportar como este", é "documentado que ele vai se comportar assim." - isto é, de " especificado para se comportar como este".
Mark Brackett

8
Isso apenas muda a questão para "por que foi especificado para se comportar assim"
CodesInChaos
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.