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?
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?
Respuestas:
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.
string.Empty
no es una constante . Eso significa que en varios casos donde se requiere una constante de tiempo de compilación, string.Empty
ni siquiera es legal. Esto incluye case ""
bloques en las switch
declaraciones, 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.Empty
no se permite en algunas situaciones comunes, es mejor usar la ""
convención -everywhere.
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.Empty
usa el código de operación ldsfld
y ""
el código de operación ldstr
, pero eso es solo porque string.Empty
es estático, y ambas instrucciones hacen lo mismo. Si observa el ensamblaje que se produce, es exactamente el mismo.
private void Test1()
{
string test1 = string.Empty;
string test11 = test1;
}
private void Test2()
{
string test2 = "";
string test22 = test2;
}
.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
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
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.Empty
o 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.
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).
Una diferencia es que si usa una switch-case
sintaxis, 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
switch
declaració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 const
campo o una variable local, const string myString = "";
la ""
opción es nuevamente . Si solo string.Empty
fuera 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?
string.Empty
evita 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.Empty
con atributos .
Yo prefiero string
a String
. elegir string.Empty
más ""
es una cuestión de elegir uno y apegarse a él. La ventaja de usar string.Empty
es que es muy obvio lo que quiere decir, y no copia accidentalmente sobre caracteres no imprimibles como "\x003"
en su ""
.
""
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.
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.Empty
y 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 .
Personalmente prefiero "" a menos que haya una buena razón para algo más complejo.
String.Empty
y string.Empty
son equivalentes String
es el nombre de la clase BCL; string
es su alias de C # (o acceso directo, si lo desea). Igual que con Int32
y int
. Ver los documentos para más ejemplos.
En lo que ""
a mí respecta, no estoy realmente seguro.
Personalmente, siempre uso string.Empty
.
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.
string.Empty
? ¿Sabías cuál ""
fue la primera vez que lo viste?
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.Empty
comillas 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.Empty
la 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.
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 Member
podría tener efectos secundarios. Si Member
es una propiedad estática con un get
descriptor de acceso, está claro que la llamada al captador debe mantenerse. Pero incluso si Member
es 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
.
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 , str2
y str3
aunque 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.
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á .
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
es sinónimo de System.String
tipo, 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.Empty
o String.Empty
- más fácil de ver lo que significaba programador.
Entre string
y String
me gusta más la minúscula string
solo 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
Me gustaría string.Empty
más String.Empty
porque 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.
string.Empty
constante sin importar el using System
espacio 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.Empty
escribe como System.String.Empty
en 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.
No hago la diferencia. Sin embargo, el último es el más rápido de escribir :)
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.
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.Empty
o 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.
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 string
o String
por coherencia, pero ese soy yo.
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.
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.
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.
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.
En http://blogs.msdn.com/b/brada/archive/2003/04/22/49997.aspx :
Como David implica, hay una diferencia entre
String.Empty
y""
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í ... mientrasString.Empty
no crea ningún objeto ... así que si realmente está buscando la eficiencia de la memoria, sugieroString.Empty
. Sin embargo, se debe tener en cuenta la diferencia es tan trivial que se vea como nunca en su código ...
En cuanto aSystem.String.Empty
ostring.Empty
oString.Empty
... mi nivel de atención es bajo ;-)
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.Empty
en 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).
Prefiero ""
porque es más corto y String.Empty
resuelve un problema que no existe.