¿Por qué Convert.ToString (null) devuelve un valor diferente si lanza null?

116
Convert.ToString(null)

devoluciones

null

Como yo esperaba.

Pero

Convert.ToString(null as object)

devoluciones

""

¿Por qué son diferentes?

John MacIntyre
fuente

Respuestas:

143

Hay 2 sobrecargas ToStringque entran en juego aquí.

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

El compilador de C # esencialmente intenta elegir la sobrecarga más específica que funcionará con la entrada. Un nullvalor es convertible a cualquier tipo de referencia. En este caso stringes más específico que objecty por lo tanto será elegido como ganador.

En el null as object, ha solidificado el tipo de expresión como object. Esto significa que ya no es compatible con la stringsobrecarga y el compilador elige la objectsobrecarga, ya que es el único compatible que queda.

Los detalles realmente complicados de cómo funciona este desempate se tratan en la sección 7.4.3 de la especificación del lenguaje C #.

JaredPar
fuente
15
Okay. Entonces está usando una sobrecarga en lugar de la otra. Tiene sentido. Pero, ¿no deberían ambas sobrecargas devolver lo mismo? +1 por cierto.
John MacIntyre
2
@JohnMacIntyre: eso depende del equipo de desarrollo, no del compilador.
JonH
8
@JohnMacIntyre Si observa la implementación de Convert.ToString(string)es solo una función de identidad, mientras que en Convert.ToString(object)realidad pasa por un camino más difícil de seguir. De un vistazo, estaría de acuerdo en que deberían devolver lo mismo, pero la capa convertible del BCL no es algo en lo que tenga mucho conocimiento y es posible que haya una buena razón para la diferencia (aunque soy escéptico)
JaredPar
Vine aquí buscando cómo convertir un objeto nulo en una cadena nula. La respuesta para otros buscadores es (string)null, o si su objeción se llama o, entonces(string)o
rayzinnz
65

Siguiendo con la excelente respuesta de resolución de sobrecarga de JaredPar, la pregunta sigue siendo "¿por qué Convert.ToString(string)devuelve nulo, pero Convert.ToString(object)vuelve string.Empty"?

Y la respuesta a eso es ... porque los documentos dicen así :

Convert.ToString (cadena) devuelve "la instancia de cadena especificada; no se realiza ninguna conversión".

Convert.ToString (objeto) devuelve "la representación de cadena del valor, o String.Empty si el valor es nulo".

EDITAR: En cuanto a si se trata de un "error en la especificación", "muy mal diseño de API", "por qué se especificó así", etc., intentaré explicar por qué no veo es tan importante.

  1. System.Converttiene métodos para convertir cada tipo base a sí mismo . Esto es extraño, ya que no se necesita ni es posible una conversión, por lo que los métodos terminan devolviendo el parámetro. Convert.ToString(string)se comporta igual. Supongo que están aquí para escenarios de generación de código.
  2. Convert.ToString(object)tiene 3 opciones cuando se aprueba null. Lanzar, devolver nulo o devolver cadena. Lanzar sería malo, doblemente si se supone que se utilizan para el código generado. Devolver nulo requiere que la persona que llama haga una verificación de nulo; de nuevo, no es una gran elección en el código generado. Devolución de cadena Vacío parece una opción razonable. El resto se System.Convertocupa de tipos de valor, que tienen un valor predeterminado.
  3. Es discutible si devolver null es más "correcto", pero string.Empty es definitivamente más utilizable. Cambiar Convert.ToString(string)significa romper la regla de "sin conversión real". Dado que System.Convertes una clase de utilidad estática, cada método puede tratarse lógicamente como propio. Hay muy pocos escenarios del mundo real donde este comportamiento debería ser "sorprendente", así que deje que la usabilidad gane sobre la (posible) corrección.
Mark Brackett
fuente
¿Es justo decir que es un error en la especificación?
John MacIntyre
3
eso no responde por qué es así. Decir que se comporta así porque está documentado que se comporta así es tautológico.
CodesInChaos
2
@JohnMacIntyre En mi opinión, es justo decir que el diseño de API es muy malo.
CodesInChaos
7
@CodeInChaos: no es una tautología, a menos que asuma que los documentos están escritos en función de un comportamiento observable después de que se desarrolló el BCL. Creo que sería una suposición extraña. OIA, no es "documenta a comportarse como este", que es "documentado que se comportan como esto." - es decir, de " especificada para comportarse así".
Mark Brackett
8
Solo cambia la pregunta a "por qué se especificó que se comportara así"
CodesInChaos