string.Empty vs null.¿Cuál usas?

84

Recientemente, un colega en el trabajo me dijo que no lo use string.Emptyal configurar una variable de cadena, sino que lo use nullya que contamina la pila.

Él dice que no lo hagas

string myString=string.Empty; pero haz string mystring=null;

¿Realmente importa? Sé que la cuerda es un objeto, así que tiene sentido.

Sé que es una pregunta tonta, pero ¿cuál es tu opinión?

usuario712923
fuente
1
No estoy del todo seguro de por qué lo haría ... ¿puede dar un poco más del código que estaba discutiendo como ejemplo?
stusmith
no hay código Le pedí a mi colega que mirara algo que estaba depurando y me dijo como regla general "no use string.empty" configúrelo en nulo a medida que va en la pila. Personalmente siempre he usado string.Empty ya que se suponía que el momento en que salió era lo correcto en lugar de "".
user712923
Lo que quiero decir es ... string.Empty, ""y nullson todos valores constantes, pero todos son lo suficientemente 'simples' como para no ver por qué asignarías uno a una variable. Si necesita capturar una outvariable, ¿por qué no usarla string myString;?
stusmith
8
En estos días, los argumentos sobre temas como este que no se centran en la legibilidad y la semántica y se centran en microoptimizaciones absurdas son, en el mejor de los casos, débiles. Utilice el que signifique lo correcto para su contexto dado. (p. ej., si sabe que alguien no tiene un segundo nombre, lo usa String.Empty; si no sabe si alguien tiene un segundo nombre que usted usa null). Luego, una vez que tenga el significado correcto, escriba el código de una manera que sea claramente correcta y fácil de mantener.
Jason

Respuestas:

110

nully Emptyson muy diferentes, y no sugiero cambiar arbitrariamente entre ellos. Pero tampoco tiene ningún "coste" extra, ya que Emptyes una única referencia fija (puedes utilizarla tantas veces como quieras).

No hay "contaminación" en la pila causada por un ldsfld - esa preocupación es .... loca. La carga de un nulles posiblemente un poco más barata, pero podría causar excepciones de referencia nula si no tiene cuidado al verificar el valor.

Personalmente, no uso ninguno ... Si quiero una cadena vacía que uso "", simple y obvio. La pasantía significa que esto tampoco tiene gastos generales por uso.


En el nivel de IL, la diferencia aquí entre "" y Empty es solo ldstr vs ldsfld, pero ambos dan la misma referencia de cadena interna única. Además, en las versiones más recientes de .NET, el JIT tiene interceptación directa de estos, lo que produce la referencia de cadena vacía sin hacer una búsqueda de campo estático. Básicamente, no hay exactamente ninguna razón para preocuparse de ninguna manera, excepto la legibilidad. Solo uso "".

Marc Gravell
fuente
5
@ user712923 si regresa con alguna inquietud concreta, me encantaría escucharla
Marc Gravell
4
@Marc: ASAIK "" crea un objeto donde string.Empty no está .. comprueba esto y esto . Tiene algo que ver con la piscina interna de cuerdas ....
Jalal Said
7
@Hemal: String.IsNullOrEmpty ()
Vinko Vrsalovic
1
+1 para usar en ""lugar de un código estándar seis veces más largo. ¡¿Quién defendió esta tontería ?! @Jalal Esa publicación de Brad Abrams está seriamente desactualizada y si el compilador aún no optimiza esos dos códigos para hacer lo mismo, ¡qué vergüenza para Microsoft! Pero no es nuestro trabajo arreglar su trabajo. Y, de hecho, no es necesario: En el segundo enlace, Lasse (en los comentarios) ha comparado los resultados del ensamblaje con cualquiera de las variantes: son idénticos.
Konrad Rudolph
1
@Konrad: Un ejemplo es lo que sucede cuando se concatenan cadenas constantes: la clase de cadena usa un grupo interno, por lo que cuando crea una nueva cadena, la clase verifica si la cadena ya está en el grupo y luego, si no la agrega al grupo. Por eso, cuando ""buscará en todo el grupo para verificar si ya está allí o no, y así es como al usar el string.Empty;, usará ese valor predefinido y la búsqueda ya no existirá. la clase también expuso estos métodos: string.Intern/IsInternedverifique esto
Jalal Said
34

No 'contamina la pila', no hay ninguna razón técnica, pero hay una gran diferencia entre establecer una variable en una referencia a un objeto (incluso si es una cadena vacía) y null. No son lo mismo y deben usarse de diferentes maneras.

nulldebe usarse para indicar la ausencia de datos, string.Empty(o "") para indicar la presencia de datos, de hecho algún texto vacío. ¿Existe algún caso específico en el que no esté seguro de cuál es el más adecuado?

Editar, ejemplos agregados:

  • Puede usarlo string.Emptycomo sufijo predeterminado para el nombre de una persona (la mayoría de las personas no tienen un doctorado, por ejemplo)

  • Puede utilizar nullpara una opción de configuración que no se especificó en el archivo de configuración. En este caso, string.Emptyse usaría si la opción de configuración estuviera presente, pero el valor configurado deseado fuera una cadena vacía.

Kieren Johnstone
fuente
Nunca pensé de esa manera, tengo que admitirlo. Dado lo que acaba de decir, ¿le importaría darme un ejemplo. Sé que su explicación se explica por sí misma, pero aún así ... gracias
user712923
2
Bueno, la única razón para elegir uno u otro se basa en el lugar donde lo usaría. Es decir, use string.Emptyo ""cuando quiera usar una cadena vacía y nullcuando quiera indicar que no hay datos. Puede usarlo string.Emptycomo sufijo predeterminado para el nombre de una persona (la mayoría de las personas no tienen un doctorado, por ejemplo) y nullpara una opción de configuración que no se especificó en el archivo de configuración. En ese segundo caso, string.Emptyse usaría si la opción de configuración estuviera presente, pero el valor configurado deseado fuera una cadena vacía.
Kieren Johnstone
@Kieren Johnstone, si uno no tiene un nombre de sufijo, ¿por qué no usarlo nullpara indicar "sin sufijo"?
OfirD
8

Son diferentes como otros ya respondieron.

static void Main(string[] args)
{
    string s1 = null;
    string s2 = string.Empty;
    string s3 = "";
    Console.WriteLine(s1 == s2);
    Console.WriteLine(s1 == s3);
    Console.WriteLine(s2 == s3);
}

 results:
 false     - since null is different from string.empty
 false     - since null is different from ""
 true      - since "" is same as string.empty

El problema con la administración de cadenas vacías frente a cadenas nulas se está convirtiendo en un problema cuando necesita conservarlo en un archivo plano o transferirlo a través de comunicaciones, por lo que creo que podría ser útil para otros que visitan esta página para dar una buena solución a ese problema en particular.

Con el fin de guardar cadenas en un archivo o comunicaciones:
probablemente desee convertir la cadena en bytes.
Una buena práctica que recomiendo es agregar 2 segmentos de bytes de encabezado a su cadena convertida.

segmento 1: metainformación que se almacena en 1 byte y describe la longitud del siguiente segmento.

segmento 2: contiene la longitud de la cadena que se va a guardar.

ejemplo:
cadena "abcd" - para simplificar la convertiré usando un codificador ASCII y obtendré {65,66,67,68}.
calcular el segmento 2 producirá 4, por lo que 4 bytes son la longitud de la cadena convertida.
calcular el segmento 1 dará como resultado 1, ya que solo se usó 1 byte para contener la información de longitud de la información de cadena convertida (que era 4, es decir, si era 260 obtendría 2)

La nueva franja de bytes ahora será {1,4,65,66,67,68} que se puede guardar en un archivo.

El beneficio con respecto al tema es que si tuviera una cadena vacía para guardar, obtendría de la conversión una matriz vacía de bytes con una longitud de 0 y, después de calcular los segmentos, terminaré teniendo {1,0} que puede ser guardado y luego cargado e interpretado de nuevo en una cadena vacía. Por otro lado, si tuviera un valor nulo en mi cadena, terminaría teniendo solo {0} como mi matriz de bytes para guardar y, nuevamente, cuando se cargue, se puede volver a interpretar como nulo.

Hay más beneficios, como saber cuál es el tamaño que se cargará o acumulará si se mueven varias cuerdas.

Volviendo al tema, será ... bueno, contaminará la pila, ya que los mismos principios descritos están siendo utilizados por cualquier sistema para diferenciar nulos de vacíos ... así que sí, cadena. Vacío toma más memoria que nulo, aunque yo no lo haría llámalo contaminación .. es sólo 1 byte más.

GY
fuente
1

Se ha respondido a muerte, pero nulo significa sin valor, no inicializado. string.Empty significa "" (una cadena en blanco) como se indica en MSDN.

La forma más segura de verificar una cadena vacía o nula es usando string.IsNullOrEmpty.

Carlos A Merighe
fuente
-2

FWIW, encontré que mezclar ""yString.Empty no funciona:

var a = "";
alert("a " + (a == "") + ", " + (a==String.Empty));   //Yields "a true, false"

var b = String.Empty;
alert("b " + (b == "") + ", " + (b == String.Empty)); //Yields "b false, true"

En particular, si usa $.trimpara obtener el valor de un campo de entrada DOM vacío, luego compárelo con String.Empty, obtendrá false. No estoy seguro de por qué es eso, pero ahí lo tienes. Ahora solo uso en ""todas partes para mayor consistencia.

usuario1072817
fuente
1
Si. Es por eso que todos deberíamos mantener el hábito de verificar .Length==0o usar.Compare()
zanlok
14
Esta pregunta se refiere a c # no js
Cole Johnson