2010-03-15 11 views
121

veo en todas partes construcciones como:ToString anulable()

int? myVar = null; 
string test = myVar.HasValue ? myVar.Value.ToString() : string.Empty; 

Por qué no usar simplemente:

string test = myVar.ToString(); 

¿No es exactamente lo mismo? Al menos Reflector dice que:

public override string ToString() 
{ 
    if (!this.HasValue) 
    { 
    return ""; 
    } 
    return this.value.ToString(); 
} 

Por lo tanto, ¿es correcto (la versión más corta) o me estoy perdiendo algo?

+0

No he visto código como este :) – mayu

Respuesta

97

Estás en lo cierto. También en this question, se sugiere la solución anterior, mientras que nadie realmente nota que ToString() ya da la respuesta correcta.

Tal vez el argumento a favor de la solución más detallada es la legibilidad: Cuando se llama a ToString() en algo que es supone ser null, por lo general espera un NullReferenceException, aunque aquí no se tira.

+17

En realidad, al menos dos personas se dieron cuenta: Eric Lippert y Johannes Rössel. –

+7

Aunque estoy seguro de que eso no es lo que quiso decir, la referencia aquí no es nula. Nullable es un tipo de valor. Esta es la razón por la cual llamar 'ToString()' funciona sin que se genere 'NullReferenceException'. – Thorarin

14

Creo que muchas personas tienen tales controles porque no es un comportamiento natural de un objeto que puede tener un valor nulo.

+0

@Andrew, de acuerdo, porque la gente (como yo) piensa al principio que arrojará una excepción. –

+0

No tenía idea de que este era el comportamiento. Definitivamente habría pensado que cualquier construcción que devuelva verdadero para (x == nulo) también arrojaría una NullReferenceException si llama a x.ToString(). –

3

puede ser solo para seguir el patrón? o ellos no conocen el back-end. tienes el código correcto es exactamente el mismo. Incluso se puede hacer:

int? i = null; 
i.ToString(); //No NullReferenceException 
+0

Puede necesitar tomar la ruta larga si ToString() debe ser de cultivo invariable, ya que los nulables no lo tienen en su menú. –

5

No, estás en lo correcto, la versión más corta es lo mismo que lo que otras personas han hecho en ese sentido. La otra construcción que suelo usar mucho en vez del ternario con nulables es el operador nulo coalescente. que también te protege de los nulos. Para ToString() no es necesario (como usted ha señalado) pero para valores int por defecto (por ejemplo) funciona muy bien, por ejemplo:

int page = currentPage ?? 1; 

que le permite hacer todas las operaciones con enteros en la página w/o explícitamente por primera vez nulo comprobando y llamando por el valor en currentPage (donde currentPage es un int? tal vez pasado como un param)

5

Lo sé, mucho después de que fuera relevante, pero ... sospecho que es porque para los tipos de nullable como int? el método .ToString() no le permite usar cadenas de formato. Ver How can I format a nullable DateTime with ToString()?. Tal vez en el código original, había una cadena de formato en .ToString(), o tal vez el codificador olvidó que .ToString() sin la cadena de formato todavía estaba disponible en tipos anulables.