2011-01-25 19 views
13

¿Por qué la segunda produce una excepción mientras que la primera no?ToString en cadena nula

string s = null; 
MessageBox.Show(s); 
MessageBox.Show(s.ToString()); 

Actualizado - la excepción que puedo entender, el bit desconcertante (para mí) es la razón por la primera parte no muestra una excepción. Esto no tiene nada que ver con el Messagebox, como se ilustra a continuación.

Ej:

string s = null, msg; 
msg = "Message is " + s; //no error 
msg = "Message is " + s.ToString(); //error 

La primera parte parece estar implícita convertir un valor nulo a una cadena en blanco.

+0

La forma más segura de hacerlo: consulte [¿Cómo hacer ToString para un objeto posiblemente nulo?] (Http://stackoverflow.com/a/3987671) –

+0

Para evitar daños 'nulos' en una cadena u objeto,' obj ?.Encadenar() ?? "" ' – bvj

Respuesta

3

Está intentando ejecutar el método ToString() en un nulo. Necesita un objeto válido para ejecutar un método.

1

La función .show debe tener una comprobación nula y manejarla.

+0

Como han dicho otros, la excepción se plantea porque se invoca un método en una referencia nula. – Vinzz

+1

De hecho. Esa es la parte obvia. – rcravens

18

porque no puede llamar al método de instancia ToString() en una referencia null.

Y MessageBox.Show() probablemente se implemente para ignorar el nulo e imprimir el cuadro de mensaje vacío.

+2

El primer bit está bien, pero creo que el bit MessageBox de mi pregunta es una distracción, de ahí mi actualización. – MartW

0

Porque, la segunda llamada espera que un objeto de "s" satisfaga una solicitud de método ToString(). entonces, antes de que se llame a .Show(), el s.ToString() fallaría con un intento de invocar un método.

Curiosamente, aunque .Show() se implementa correctamente, muchos de estos métodos esperan que se entreguen instancias no nulas. Generalmente, es cuando se utiliza un patrón NullObject para que la persona que llama no tenga que tratar con este tipo de comportamiento.

0

Probablemente el método Show maneja un valor nulo y simplemente no muestra nada. El segundo uso de s - s.ToString() falla porque no hay un método ToString para ejecutar.

12

Es porque MessageBox.Show() se implementa con pinvoke, llama a la función nativa de Windows MessageBox(). Lo cual no le importa obtener un NULL para el argumento lpText. El lenguaje C# tiene reglas mucho más estrictas para los métodos puros de instancia .NET (como ToString), siempre emite código para verificar que el objeto no sea nulo. Hay información de fondo sobre eso en este blog post.

+3

+1: ¡Interesante e informativo! – gbvb

4

Detrás del concat escenas que se está llamando en su seguimiento de pregunta/actualización Ej

string snull = null; 

string msg = "hello" + snull; 

// is equivalent to the line below and concat handles the null string for you. 
string msg = String.Concat("hello", snull); 

// second example fails because of the toString on the null object 
string msg = String.Concat("hello", snull.ToString()); 

//String.Format, String.Convert, String.Concat all handle null objects nicely. 
+2

¿Puede mostrarnos esto * entre bastidores * porque seguramente no puedo encontrarlo en mscorlib ... –

+0

¿Quiere decir que los métodos de String solo lo convierten en cadena 'nulo' si el valor devuelto es nulo? –

+0

@RobertKoritnik Use ildasm.exe en el código de ejemplo compilado, y verá lo que James escribió. – Kobor42

0

Como esta cuestión ocupa bastante alta en Google para una búsqueda de "C# toString nulo", me gustaría añadir que el método Convert.ToString(null) devolvería una cadena vacía.

Sin embargo, para reafirmar las otras respuestas, puede usar string.Concat("string", null) en este ejemplo.

Cuestiones relacionadas