isnullorwhitespace empty check c# .net string null

empty - string null c#



¿Por qué es válido concatenar cadenas nulas pero no llamar a "null.ToString()"? (11)

Este es un código válido de C #

var bob = "abc" + null + null + null + "123"; // abc123

Este no es un código válido de C #

var wtf = null.ToString(); // compiler error

¿Por qué es válida la primera declaración?


Agregar null a una cadena simplemente se ignora. null (en su segundo ejemplo) no es una instancia de ningún objeto, por lo que ni siquiera tiene un método ToString() . Es solo un literal.


Alguien dijo en este hilo de discusión que no se puede hacer una cadena de nada. (que es una frase agradable, como creo). Pero sí, puedes :-), como se muestra en el siguiente ejemplo:

var x = null + (string)null; var wtf = x.ToString();

funciona bien y no arroja ninguna excepción. La única diferencia es que debe convertir uno de los valores nulos en una cadena; si elimina el molde (de cadena) , entonces el ejemplo aún se compila, pero arroja una excepción en tiempo de ejecución: "Operador ''+'' es ambiguo en los operandos de escriba ''<null>'' y ''<null>'' ".

NB En el ejemplo de código anterior, el valor de x no es nulo como cabría esperar, en realidad es una cadena vacía después de haber convertido uno de los operandos en una cadena.

Otro hecho interesante es que en C # / .NET la forma en que se trata el null no es siempre la misma si se consideran diferentes tipos de datos. Por ejemplo:

int? x = 1; // string x = "1"; x = x + null + null; Console.WriteLine((x==null) ? "<null>" : x.ToString());

Observe la primera línea del fragmento de código: si x es una variable entera nulable (es decir, int? ) Que contiene el valor 1 , entonces obtendrá el resultado <null> nuevo. Si se trata de una cadena (como se muestra en el comentario) con el valor "1" , entonces obtendrá "1" en lugar de <null> .

NB También es interesante: si usa var x = 1; para la primera línea, entonces está obteniendo un error de tiempo de ejecución. ¿Por qué? Porque la asignación convertirá la variable x en el tipo de datos int , que no puede contener nulos. El compilador no asume int? aquí, y por lo tanto falla en la 2da línea donde se agrega null .


Como general: puede o no validar la aceptación de nulo como un parámetro que depende de la especificación, pero siempre es inválido llamar a un método en nulo.

Ese y otro tema explican por qué los operandos del operador + pueden ser nulos en caso de cadenas. Esto es algo parecido a VB (lo siento chicos) para facilitar la vida de los programadores, o suponiendo que el programador no puede lidiar con nulos. Estoy completamente en desacuerdo con esta especificación. ''desconocido'' + ''cualquier cosa'' debería ser ''desconocido'' ...


En el marco COM que precedió a .net, era necesario que cualquier rutina que recibiera una cadena lo liberara cuando terminara con él. Debido a que era muy común que las cadenas vacías ingresaran y salieran de las rutinas, y porque intentar "liberar" un puntero nulo se definió como una operación legítima de no hacer nada, Microsoft decidió que un puntero de cadena nulo representara una cadena vacía.

Para permitir cierta compatibilidad con COM, muchas rutinas en .net interpretarán un objeto nulo como una representación legal como una cadena vacía. Con un par de cambios ligeros de .net y sus lenguajes (lo que más notablemente permite a los miembros de la instancia indicar "no invocar como virtual"), Microsoft podría haber hecho que null objetos null del tipo declarado Cadena se comportaran aún más como cadenas vacías. Si Microsoft lo hubiera hecho, también habría tenido que hacer que Nullable<T> funcionara de manera algo diferente (para permitir Nullable<String> --algo que deberían haber hecho en mi humilde opinión) y / o definir un tipo de NullableString que sería en su mayoría intercambiable con String , pero que no consideraría un null como una cadena vacía válida.

Tal como están las cosas, hay algunos contextos en los que un null se considerará una cadena vacía legítima y otros en los que no se considerará. No es una situación terriblemente útil, pero de la cual los programadores deberían estar conscientes. En general, las expresiones de la forma stringValue.someMember fallarán si stringValue es null , pero la mayoría de los métodos de framework y operadores que aceptan strings como parámetros considerarán null como una cadena vacía.


La primera muestra se traducirá a:

var bob = String.Concat("abc123", null, null, null, "abs123");

El método Concat comprueba la entrada y traduce null como una cadena vacía

La segunda muestra se traducirá a:

var wtf = ((object)null).ToString();

Entonces, se generará una excepción de referencia null aquí


La primera parte de tu código solo se trata así en String.Concat ,

que es lo que llama el compilador C # cuando agrega cadenas. " abc" + null se traduce a String.Concat("abc", null) ,

e internamente, ese método reemplaza null con String.Empty . Entonces, esa es la razón por la cual la primera parte del código no arroja ninguna excepción. es como

var bob = "abc" + string.Empty + string.Empty + string.Empty + "123"; //abc123

Y en la segunda parte de su código lanza una excepción porque ''nulo'' no es un objeto, la palabra clave nula es un literal que representa una referencia nula , una que no se refiere a ningún objeto. null es el valor predeterminado de las variables de tipo de referencia.

Y '' ToString() '' es un método que puede llamar una instancia de un objeto pero no un literal.


Porque el operador + en C # se traduce internamente a String.Concat , que es un método estático. Y este método pasa a tratar null como una cadena vacía. Si miras la fuente de String.Concat en Reflector, lo verás:

// while looping through the parameters strArray[i] = (str == null) ? Empty : str; // then concatenate that string array

(MSDN lo menciona también: http://msdn.microsoft.com/en-us/library/k9c94ey1.aspx )

Por otro lado, ToString() es un método de instancia, que no puede invocar en null (¿qué tipo debe usarse para null ?).


Porque no hay diferencia entre string.Empty y null cuando concat cadenas. Puedes pasar null a string.Format también. Pero está intentando llamar a un método en null , lo que siempre daría como resultado una NullReferenceException y, por lo tanto, genera un error de compilación.
Si por alguna razón realmente quieres hacerlo, podrías escribir un método de extensión que verifique null y luego devuelva string.Empty . Pero una extensión como esa solo debe usarse cuando sea absolutamente necesario (en mi opinión).


Supongo porque es un literal que no se refiere a ningún objeto. ToString() necesita un object .


''+'' es un operador infijo. Como cualquier operador, realmente está llamando a un método. Se podría imaginar una versión no infija "wow".Plus(null) == "wow"

El implementador ha decidido algo como esto ...

class String { ... String Plus(ending) { if(ending == null) return this; ... } }

Entonces ... tu ejemplo se convierte

var bob = "abc".Plus(null).Plus(null).Plus(null).Plus("123"); // abc123

que es lo mismo que

var bob = "abc".Plus("123"); // abc123

En ningún punto nulo se convierte en una cadena. Entonces null.ToString() no es diferente que null.VoteMyAnswer() . ;)


La razón por la que uno trabaja:

Desde MSDN :

En las operaciones de concatenación de cadenas, el compilador de C # trata una cadena nula igual que una cadena vacía, pero no convierte el valor de la cadena nula original.

Más información sobre el + operador binario :

El operador binario + realiza la concatenación de cadenas cuando uno o ambos operandos son de tipo cadena.

Si un operando de concatenación de cadenas es nulo, se sustituye una cadena vacía. De lo contrario, cualquier argumento que no sea cadena se convierte a su representación de cadena invocando el método virtual ToString heredado de tipo objeto.

Si ToString devuelve null , se sustituye una cadena vacía.

El motivo del error en el segundo es:

null (Referencia C #) - La palabra clave null es un literal que representa una referencia nula, una que no se refiere a ningún objeto. null es el valor predeterminado de las variables de tipo de referencia.