En C #, ¿debo usar string.Empty o String.Empty o "" para inicializar una cadena?


705

En C #, quiero inicializar un valor de cadena con una cadena vacía.

¿Cómo debería hacer esto? ¿Cuál es el camino correcto y por qué?

string willi = string.Empty;

o

string willi = String.Empty;

o

string willi = "";

¿o que?


77
Vea también esta discusión similar para java: stackoverflow.com/questions/213985/…
harpo

39
es mejor usar String.IsNullOrEmpty (string myString), ¿no?
ZombieSheep

3
Yo uso [string.IsNullOrWhiteSpace (stringvalue)] ... funciona en .Net 4.0. Para inicializar, simplemente uso: [var text = "";] Simple, legible y toma el menor tiempo para escribir :)
Jalal El-Shaer

61
Lo que es más importante es el nombre hilarante de su variable.
Arj

55
Lo que me ha interesado es por qué hay incluso una propiedad vacía. Es agradable y todo, pero no es necesario y completo.
MasterMastic

Respuestas:


808

Use lo que usted y su equipo encuentren lo más legible.

Otras respuestas han sugerido que se crea una nueva cadena cada vez que la usa "". Esto no es cierto: debido al internamiento de cadenas, se creará una vez por ensamblaje o una vez por AppDomain (o posiblemente una vez para todo el proceso, no estoy seguro en ese aspecto). Esta diferencia es insignificante: masiva, masivamente insignificante.

Sin embargo, lo que encuentre más legible es un asunto diferente. Es subjetivo y variará de una persona a otra, por lo que le sugiero que descubra lo que le gusta a la mayoría de las personas de su equipo, y que todo sea coherente. Personalmente me resulta ""más fácil de leer.

El argumento que ""y " "fácilmente se confunden el uno con el otro en realidad no está de acuerdo conmigo. A menos que esté usando una fuente proporcional (y no he trabajado con ningún desarrollador que lo haga), es bastante fácil notar la diferencia.


75
Tus ojos pueden engañarte cuando esperas ver "" puedes confundir fácilmente "" con "". Es por eso que es más fácil editar algo que alguien más ha escrito. Su cerebro no tiene ideas preconcebidas sobre el texto, por lo que es más fácil elegir los anonimatos.
tvanfosson el

125
@tvanfosson: Entonces, ¿usted (o un colega) realmente fue mordido por esto como un error? Sospecho de este tipo de reclamo sin que realmente haya causado problemas. He estado usando "" durante años sin equivocarme nunca ...
Jon Skeet

34
Personalmente, siempre he usado String. Vacío, uso 'S' mayúscula cada vez que quiero usar un método estático en cadena, es solo una preferencia personal que me permite distinguir un tipo de una variable. Pero esto es solo una transferencia del uso de StringUtils.EMPTY en commons.lang de java. Un punto de interés es que estoy casi ciego y esto definitivamente me ayuda con la legibilidad.
Brett Ryan, el

79
Me has dado la inspiración para comenzar a desarrollar en Times New Roman.
Justin Rusbatch

73
Por alguna oscura razón string.Emptyno es una constante . Eso significa que en varios casos donde se requiere una constante de tiempo de compilación, string.Emptyni siquiera es legal. Esto incluye case ""bloques en las switchdeclaraciones, valores predeterminados de parámetros opcionales , parámetros y propiedades en la aplicación de atributos , y muchas otras situaciones (dejadas al lector). Por lo tanto, dado que string.Emptyno se permite en algunas situaciones comunes, es mejor usar la ""convención -everywhere.
Jeppe Stig Nielsen

375

Realmente no hay diferencia desde el punto de vista de rendimiento y código generado. En las pruebas de rendimiento, iban y venían entre uno y otro más rápido, y solo por milisegundos.

Al mirar el código detrás de escena, realmente tampoco ves ninguna diferencia. La única diferencia está en el IL, que string.Emptyusa el código de operación ldsfld y ""el código de operación ldstr, pero eso es solo porque string.Emptyes estático, y ambas instrucciones hacen lo mismo. Si observa el ensamblaje que se produce, es exactamente el mismo.

Código C #

private void Test1()
{
    string test1 = string.Empty;    
    string test11 = test1;
}

private void Test2()
{
    string test2 = "";    
    string test22 = test2;
}

Código IL

.method private hidebysig instance void 
          Test1() cil managed
{
  // Code size       10 (0xa)
  .maxstack  1
  .locals init ([0] string test1,
                [1] string test11)
  IL_0000:  nop
  IL_0001:  ldsfld     string [mscorlib]System.String::Empty
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  stloc.1
  IL_0009:  ret
} // end of method Form1::Test1
.method private hidebysig instance void 
        Test2() cil managed
{
  // Code size       10 (0xa)
  .maxstack  1
  .locals init ([0] string test2,
                [1] string test22)
  IL_0000:  nop
  IL_0001:  ldstr      ""
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  stloc.1
  IL_0009:  ret
} // end of method Form1::Test2

Código de montaje

        string test1 = string.Empty;
0000003a  mov         eax,dword ptr ds:[022A102Ch] 
0000003f  mov         dword ptr [ebp-40h],eax 

        string test11 = test1;
00000042  mov         eax,dword ptr [ebp-40h] 
00000045  mov         dword ptr [ebp-44h],eax 
        string test2 = "";
0000003a  mov         eax,dword ptr ds:[022A202Ch] 
00000040  mov         dword ptr [ebp-40h],eax 

        string test22 = test2;
00000043  mov         eax,dword ptr [ebp-40h] 
00000046  mov         dword ptr [ebp-44h],eax 

13
@PrateekSaluja: Para ver la IL, puede usar ildasm.exe, que se incluye con Visual Studio. Para ver el desensamblaje, use la ventana 'Desmontaje' en el menú de depuración cuando llegue a un punto de interrupción (también funciona en el código de liberación).
Thomas Bratt

1
Odio que estoy a punto de recomendar este producto ... PERO ... ¡el reflector le permite elegir su idioma al desmontar la fuente e IL es una opción! ILDASM acaba de sentirse ... ¡el equipo de herramientas de MS no parece pulir ni lanzar las buenas herramientas!
felickz

80

El mejor código es ningún código :

La naturaleza fundamental de la codificación es que nuestra tarea, como programadores, es reconocer que cada decisión que tomamos es una compensación. […] Comience con brevedad. Aumente las otras dimensiones según lo requiera la prueba.

En consecuencia, menos código es mejor código: Prefiero ""a string.Emptyo String.Empty. Esos dos son seis veces más largos sin beneficio adicional, ciertamente no tienen claridad adicional, ya que expresan exactamente la misma información.


1
pero en C # solo podemos decir string.IsNullOrWhitespace (s): p
felickz

31
Estoy de acuerdo en que el código debe ser lo más pequeño posible, pero en general no argumentaría que menos caracteres siempre es mejor código. Cuando se trata de nombres variables, por ejemplo, una cantidad razonable de caracteres generalmente da como resultado mejores nombres que simplemente usar iy j.
Markus Meyer

3
@ Markus Eso depende mucho: para una variable de bucle que representa un índice, i es mejor que un nombre de variable largo. Aún más general, siempre son preferibles los nombres de variables más cortos que transmiten la misma información , con la misma claridad. Es solo que para expresar la información necesaria necesitas una cierta longitud de caracteres, y no estoy negando esto (nadie lo es).
Konrad Rudolph el

2
@ Konrad: i es un buen nombre de variable solo si el bucle es pequeño y no contiene ningún otro índice. Pero estoy de acuerdo en que si algo. se puede indicar más brevemente transmitiendo la misma información, que sería preferible, como en el caso string.Empty / "". La cadena vacía no agrega ninguna claridad.
Markus Meyer

Para mí: string.Empty dice que esta cadena está y debe estar vacía en todo momento, mientras que "" dice que al momento de escribir esta cadena podría estar vacía, pero puede cambiarla.
aeroson

54

Una diferencia es que si usa una switch-casesintaxis, no puede escribir case string.Empty:porque no es una constante. Obtienes unCompilation error : A constant value is expected

Mire este enlace para más información: string-empty-versus-empty-quotes


22
La switchdeclaración es un muy buen ejemplo. Además, si crea un parámetro opcional, como void MyMethod(string optional = "") { ... }, tampoco es posible usarlo string.Empty. Y, por supuesto, si desea definir un constcampo o una variable local, const string myString = "";la ""opción es nuevamente . Si solo string.Emptyfuera un campo constante, no habría diferencia. Pero no lo es, así que en algunos casos tienes que usar "". Entonces, ¿por qué no usar ""todo el tiempo?
Jeppe Stig Nielsen

55
Este es un argumento realmente fuerte porque el uso string.Emptyevita que consigas consistencia en tu base de código: debes usar dos entidades diferentes para expresar lo mismo. Y para agregar a la lista de cosas que no puede hacer: no puede usar string.Emptycon atributos .
Pragmateek

2
Muy buenos puntos! El enlace está roto. Aquí hay una copia del contenido: web.archive.org/web/20131230161806/http://kossovsky.net/…
ygoe

42

Yo prefiero stringa String. elegir string.Emptymás ""es una cuestión de elegir uno y apegarse a él. La ventaja de usar string.Emptyes que es muy obvio lo que quiere decir, y no copia accidentalmente sobre caracteres no imprimibles como "\x003"en su "".


101
Yo diría que si está copiando accidentalmente caracteres no imprimibles en su código, tiene mayores problemas que esta pregunta;)
Jon Skeet

99
ASCII \ 003 resulta ser un delimitador de campo para mensajes B2B con los que he trabajado :)
Jimmy

77
(También sugiero evitar el \ x escape, por cierto, es demasiado difícil detectar la diferencia entre "\ x9Bad Compiler" y "\ x9Good Compiler" que tienen resultados radicalmente diferentes).
Jon Skeet

Personalmente, prefiero String sobre string cuando llamo a un método estático en String. Sin embargo, estoy casi ciego y esta es una preferencia personal que no impongo a nadie.
Brett Ryan, el

2
@ Jimmy Claro, pero estábamos hablando de la cadena vacía. El argumento que ""es peligroso cuando copiar / pegar es nulo, afirmo, porque nunca se copia / pega la cadena vacía. Para otras cadenas, siempre es algo a tener en cuenta, por supuesto.
Timo

22

No iba a intervenir, pero veo que se arroja información incorrecta aquí.

Yo personalmente prefiero string.Empty. Esa es una preferencia personal, y me doblego a la voluntad de cualquier equipo con el que trabaje caso por caso.

Como otros han mencionado, no hay ninguna diferencia entre string.Emptyy String.Empty.

Además, y este es un hecho poco conocido, usar "" es perfectamente aceptable. Cada instancia de "" creará, en otros entornos, un objeto. Sin embargo, .NET pasa sus cadenas, por lo que las instancias futuras extraerán la misma cadena inmutable del grupo interno y cualquier impacto en el rendimiento será insignificante. Fuente: Brad Abrams .


20
No veo por qué "técnicamente" cada instancia de "" creará un objeto. No es solo casualidad que las cadenas estén internadas, está en la especificación C #.
Jon Skeet el

15

Personalmente prefiero "" a menos que haya una buena razón para algo más complejo.


13

String.Emptyy string.Emptyson equivalentes Stringes el nombre de la clase BCL; stringes su alias de C # (o acceso directo, si lo desea). Igual que con Int32y int. Ver los documentos para más ejemplos.

En lo que ""a mí respecta, no estoy realmente seguro.

Personalmente, siempre uso string.Empty.


10

Casi todos los desarrolladores sabrán qué significa "". Personalmente, encontré String.Empty la primera vez y tuve que pasar algún tiempo buscando en Google para descubrir si realmente son exactamente lo mismo.


3
Es un campo de cadena de solo lectura público y sus valores son "" ... ¿por qué cambiaría eso?
Matthew Whited

55
Echas de menos el punto que hace @Jason. ¿Cómo sabes qué es la primera vez que ves string.Empty? ¿Sabías cuál ""fue la primera vez que lo viste?
David R Tribble

10

Este tema es bastante antiguo y largo, así que discúlpeme si este comportamiento se ha mencionado en otro lugar. (Y señalarme la respuesta que cubre esto)

He encontrado una diferencia en el comportamiento del compilador si usa string.Emptycomillas dobles. La diferencia se muestra si no utiliza la variable de cadena inicializada con string. Vacío o con comillas dobles.

En caso de inicialización con string.Emptyla advertencia del compilador

CS0219 - The variable 'x' is assigned but its value is never used

nunca se emite mientras que en caso de inicialización con comillas dobles se obtiene el mensaje esperado.

Este comportamiento se explica en el artículo de Connect en este enlace: https://connect.microsoft.com/VisualStudio/feedback/details/799810/c-warning-cs0219-not-reported-when-assign-non-constant-value

Básicamente, si lo hago bien, quieren permitir que un programador establezca una variable con el valor de retorno de una función para fines de depuración sin molestarlo con un mensaje de advertencia y, por lo tanto, limitaron la advertencia solo en caso de asignaciones y cadenas costosas. Vacío no es una constante sino un campo.


1
Creo que eres el primero en mencionar. He leído estas preguntas y respuestas hace varios meses y no recuerdo esta diferencia, lo que haría si hubiera sido mencionada.
Palec

2
Interesante. Tenga en cuenta que var unused = "literal";el compilador puede eliminar (eliminar) por completo una declaración . No puede tener efectos secundarios. Por otro lado, var unused = MyClass.Member;no se puede eliminar por completo. Eso es porque la lectura Memberpodría tener efectos secundarios. Si Memberes una propiedad estática con un getdescriptor de acceso, está claro que la llamada al captador debe mantenerse. Pero incluso si Memberes un campo estático, puede haber el efecto secundario que puede ejecutar el constructor estático. Seguro que sería un mal estilo de codificación tenerlo de esa manera. Pero necesitas un muñeco para leer Member.
Jeppe Stig Nielsen

9

Realicé esta prueba muy simple usando el siguiente método en una aplicación de consola:

private static void CompareStringConstants()
{
    string str1 = "";
    string str2 = string.Empty;
    string str3 = String.Empty;
    Console.WriteLine(object.ReferenceEquals(str1, str2)); //prints True
    Console.WriteLine(object.ReferenceEquals(str2, str3)); //prints True
}

Esto sugiere claramente que las tres variables str1, a saber , str2y str3aunque se inicializan con una sintaxis diferente, apuntan exactamente al mismo objeto de cadena (de longitud cero) en la memoria. Realicé esta prueba en la aplicación de consola .NET 4.5. Por lo tanto, internamente no tienen ninguna diferencia y todo se reduce a la conveniencia de cuál desea usar como programador. Este comportamiento de la clase de cadena se conoce como cadena interna en .NET. Eric Lippert tiene un blog muy agradable aquí que describe este concepto.


8

Cualquiera de los anteriores.

Hay muchas, muchas cosas mejores para pontificar. Como el color de la corteza que mejor se adapta a un árbol, creo que es marrón vago con tintes de musgo dulce.


7

Prefiero encarecidamente String.Empty, aparte de las otras razones para asegurarme de saber qué es y de que no ha eliminado accidentalmente el contenido, sino principalmente para la internacionalización. Si veo una cadena entre comillas, siempre tengo que preguntarme si ese es un código nuevo y si debe colocarse en una tabla de cadenas. Entonces, cada vez que se cambia / revisa el código, debe buscar "algo entre comillas" y sí, puede filtrar las cadenas vacías, pero le digo a las personas que es una buena práctica nunca poner cadenas entre comillas a menos que sepa que no se localizará .


7

Nadie mencionó que en VisualStudio la cadena tiene un código de color diferente que la cadena. Lo cual es importante para la legibilidad. Además, la minúscula se usa generalmente para vars y type, no es un gran problema, pero String.Empty es una constante y no un var o type.


String.Empty no es una constante: consulte stackoverflow.com/questions/507923/… Es en realidad una instancia de la clase String, por diseño. Y el color se mencionó antes aunque un poco oculto: stackoverflow.com/questions/263191/…
Michael

6

stringes sinónimo de System.Stringtipo, son idénticos.

Los valores también son idénticos: string.Empty == String.Empty == ""

Yo no usaría constante de carácter "" en el código, en lugar string.Emptyo String.Empty- más fácil de ver lo que significaba programador.

Entre stringy Stringme gusta más la minúscula stringsolo porque solía trabajar con Delphi durante muchos años y el estilo de Delphi es minúscula string.

Entonces, si yo fuera tu jefe, estarías escribiendo string.Empty


6

Me gustaría string.Emptymás String.Emptyporque puedes usarlo sin necesidad de incluir un using System;en tu archivo.

En cuanto a la recogida ""sobre string.Empty, es la preferencia personal y debe ser decidido por su equipo.


2
Soy el único miembro del equipo, ¿cómo decido? ¿Tirar un dado?
Gqqnbig

1
Para aquellos que se preguntan cómo es posible usar string.Emptyconstante sin importar el using Systemespacio de nombres: las palabras clave en C # simplemente se convierten a su nombre completo que incluye el espacio de nombres antes de escribirse como MSIL en la salida * .dll o *. archivo exe. De manera efectiva, el compilador lo string.Emptyescribe como System.String.Emptyen el MSIL. Y como ya sabrá, si menciona un nombre de tipo completamente calificado, puede omitir la importación de espacios de nombres en la parte superior de su archivo de código.
RBT

5

No hago la diferencia. Sin embargo, el último es el más rápido de escribir :)


4

No importa, son exactamente lo mismo. Sin embargo, lo principal es que debes ser consistente

PD: Lucho con este tipo de "cuál es la cosa correcta" todo el tiempo.


1
En el mundo moderno, "consistente" significa consistente en todos los equipos del mundo, que es uno de los objetivos de StackOverflow. Si puedo sugerir, usemos String.Empty.
Pavel Radzivilovsky

1
Algunos idiomas no tienen una constante vacía, y todos los idiomas que se me ocurren permiten "" una cadena de longitud cero. Así que voto por "" la coherencia con otros idiomas. :)
TomXP411

4

Es totalmente una preferencia de estilo de código, haz cómo .NET maneja las cadenas. Sin embargo, aquí están mis opiniones :)

Siempre uso los nombres de tipo BCL cuando accedo a métodos estáticos, propiedades y campos: String.Emptyo Int32.TryParse(...)oDouble.Epsilon

Siempre uso las palabras clave de C # cuando declaro nuevas instancias: int i = 0;ostring foo = "bar";

Raramente uso literales de cadena no declarados, ya que me gusta poder escanear el código para combinarlos en constantes con nombre reutilizables. De todos modos, el compilador reemplaza las constantes con los literales, por lo que es más una forma de evitar cadenas / números mágicos y darles un poco más de significado con un nombre. Además, cambiar los valores es más fácil.


3

Yo uso el tercero, pero de los otros dos el primero parece menos extraño. string es un alias para String, pero verlos a través de una tarea se siente mal.


3

Cualquiera de los dos primeros sería aceptable para mí. Evitaría el último porque es relativamente fácil introducir un error al poner un espacio entre las comillas. Este error en particular sería difícil de encontrar por observación. Suponiendo que no hay errores tipográficos, todos son semánticamente equivalentes.

[EDITAR]

Además, es posible que desee usar siempre uno stringo Stringpor coherencia, pero ese soy yo.


Estoy de acuerdo con este comentario, pero aún vivo peligrosamente cuando soy flojo. En cualquier caso, no creo que tenga ocasión de escribir código que use una cadena antes de asignarla fuera de la declaración de variable. De hecho, es molesto para mí tener que inicializar mis cadenas, a pesar de los riesgos.
EnocNRoll - AnandaGopal Pardue

3

Personalmente he presenciado "" como resultado problemas (menores) dos veces. Una vez se debió a un error de un desarrollador junior nuevo en la programación basada en equipo, y la otra fue un error tipográfico simple, pero el hecho es usar string. Vacío habría evitado ambos problemas.

Sí, esto es en gran medida una cuestión de criterio, pero cuando un lenguaje le brinda múltiples formas de hacer las cosas, tiendo a inclinarme hacia el que tiene la mayor supervisión del compilador y la aplicación más sólida en tiempo de compilación. Eso no es "". Se trata de expresar una intención específica.

Si escribe string.EMpty o Strng.Empty, el compilador le informa que lo hizo mal. Inmediatamente. Simplemente no se compilará. Como desarrollador, está citando la intención específica de que el compilador (u otro desarrollador) no pueda malinterpretar de ninguna manera, y cuando lo hace mal, no puede crear un error.

Si escribe "" cuando quiera decir "" o viceversa, el compilador felizmente hace lo que le dijo que hiciera. Otro desarrollador puede o no ser capaz de obtener su intención específica. Error creado.

Mucho antes que string. Vacío era algo que había usado una biblioteca estándar que definía la constante EMPTY_STRING. Todavía usamos esa constante en las declaraciones de caso donde string.Empty no está permitido.

Siempre que sea posible, ponga el compilador a trabajar para usted y elimine la posibilidad de error humano, por pequeño que sea. En mi opinión, esto supera la "legibilidad" como otros han citado.

Especificidad y tiempo de compilación. Es lo que hay para cenar.


3

Uso "" porque tendrá un color distintivo amarillo en mi código ... por alguna razón String.Empty es todo blanco en mi tema de Visual Studio Code. Y creo que eso es lo que más me importa.


2

El compilador debería hacerlos todos iguales a largo plazo. Elija un estándar para que su código sea fácil de leer y manténgalo.


2

Estaba mirando un código y me vino a la mente esta pregunta que había leído un poco antes. Esta es ciertamente una cuestión de legibilidad.

Considere el siguiente código C # ...

(customer == null) ? "" : customer.Name

vs

(customer == null) ? string.empty : customer.Name

Personalmente, este último me parece menos ambiguo y más fácil de leer.

Como señalaron otros, las diferencias reales son insignificantes.


1

Creo que el segundo es "apropiado", pero para ser honesto, no creo que importe. El compilador debe ser lo suficientemente inteligente como para compilar cualquiera de ellos con el mismo código de bytes. Yo me uso "".


1

Si bien la diferencia es muy, MUY pequeña, la diferencia aún existe.

1) "" crea un objeto mientras que String.Empty no. Pero este objeto se creará una vez y se hará referencia desde el grupo de cadenas más adelante si tiene otro "" en el código.

2) String y string son lo mismo, pero recomendaría usar String.Empty (así como String.Format, String.Copy, etc.) ya que la notación de puntos indica clase, no operador, y que la clase que comienza con mayúscula se ajuste a C # estándares de codificación.


1
string.Empty is "", verifique la fuente
dss539

1

En http://blogs.msdn.com/b/brada/archive/2003/04/22/49997.aspx :

Como David implica, hay una diferencia entre String.Emptyy ""son bastante pequeñas, pero hay una diferencia. ""en realidad crea un objeto, es probable que sea sacado del grupo interno de cadenas, pero aún así ... mientras String.Emptyno crea ningún objeto ... así que si realmente está buscando la eficiencia de la memoria, sugiero String.Empty. Sin embargo, se debe tener en cuenta la diferencia es tan trivial que se vea como nunca en su código ...
En cuanto a System.String.Emptyo string.Emptyo String.Empty... mi nivel de atención es bajo ;-)


1
Esa publicación de blog de MSDN fue en 2003 ... ¿estás seguro de que esto sigue siendo cierto para las versiones recientes de .NET?
Carsten Schütte el

@ CarstenSchütte: Me parece que esa característica no está destinada a cambiar mucho ... y si lo fue, hubo algo de rumores en Internet al respecto.
sergiol

3
@sergiol Si un campo es más eficiente que un literal, entonces esto es inequívocamente un error de rendimiento. Así que hay esperanzas de que ya esté solucionado.
Konrad Rudolph el

1

La cadena vacía es como un conjunto vacío, solo un nombre que todos usan para llamar "". También en los idiomas formales, las cadenas creadas a partir de un alfabeto que tienen longitud cero se denominan cadenas vacías. Tanto set como string tienen un símbolo especial para ello. Cadena vacía: ε y conjunto vacío: ∅. Si desea hablar sobre esta cadena de longitud cero, la llamará la cadena vacía para que todos sepan exactamente a qué se refiere. Ahora, en caso de que lo nombre la cadena vacía, ¿por qué no usarlo string.Emptyen el código ?, muestra que la intención es explícita Lo malo es que no es una constante y, por lo tanto, no está disponible en todas partes, como en los atributos. (No es una constante por algunas razones técnicas, consulte la fuente de referencia).


0

Prefiero ""porque es más corto y String.Emptyresuelve un problema que no existe.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.