¿Cuál es la diferencia entre String y string en C#?
Pregunta
Ejemplo (tenga en cuenta el caso):
string s = "Hello world!";
String s = "Hello world!";
¿Cuáles son los pautas para el uso de cada uno?¿Y cuáles son los diferencias?
Solución
string
es un alias en C# para System.String
.
Así que técnicamente no hay diferencia.Es como int
vs. System.Int32
.
En cuanto a las pautas, generalmente se recomienda utilizar string
cada vez que te refieres a un objeto.
p.ej.
string place = "world";
Asimismo, creo que generalmente se recomienda utilizar String
si necesita referirse específicamente a la clase.
p.ej.
string greet = String.Format("Hello {0}!", place);
Este es el estilo que Microsoft suele utilizar en sus ejemplos.
Parece que la orientación en esta área puede haber cambiado, ya que EstiloCop ahora impone el uso de alias específicos de C#.
Otros consejos
Sólo para completar, aquí hay un volcado de información relacionada...
Como otros han señalado, string
es un alias para System.String
.Se compilan con el mismo código, por lo que en el momento de la ejecución no hay diferencia alguna.Este es sólo uno de los alias en C#.La lista completa es:
object: System.Object
string: System.String
bool: System.Boolean
byte: System.Byte
sbyte: System.SByte
short: System.Int16
ushort: System.UInt16
int: System.Int32
uint: System.UInt32
long: System.Int64
ulong: System.UInt64
float: System.Single
double: System.Double
decimal: System.Decimal
char: System.Char
Aparte de string
y object
, todos los alias son para tipos de valor. decimal
es un tipo de valor, pero no un tipo primitivo en CLR.El único tipo primitivo que no tiene alias es System.IntPtr
.
En la especificación, los alias de tipos de valores se conocen como "tipos simples".Los literales se pueden utilizar para valores constantes de todo tipo simple;ningún otro tipo de valor tiene formas literales disponibles.(Compare esto con VB, que permite DateTime
literales y también tiene un alias).
Hay una circunstancia en la que usted tener para usar los alias:al especificar explícitamente el tipo subyacente de una enumeración.Por ejemplo:
public enum Foo : UInt32 {} // Invalid
public enum Bar : uint {} // Valid
Eso es sólo una cuestión de la forma en que la especificación define las declaraciones de enumeración: la parte después de los dos puntos tiene que ser la tipo integral producción, que es una muestra de sbyte
, byte
, short
, ushort
, int
, uint
, long
, ulong
, char
...en contraposición a un tipo producción como lo utilizan las declaraciones de variables, por ejemplo.No indica ninguna otra diferencia.
Finalmente, cuando se trata de cuál usar:Personalmente uso los alias en todas partes para la implementación, pero el tipo CLR para cualquier API.Realmente no importa demasiado cuál utilices en términos de implementación: la coherencia entre tu equipo es buena, pero a nadie más le importará.Por otro lado, es realmente importante que si hace referencia a un tipo en una API, lo haga en un idioma neutral.Un método llamado ReadInt32
es inequívoco, mientras que un método llamado ReadInt
requiere interpretación.La persona que llama podría estar usando un lenguaje que defina un int
alias para Int16
, Por ejemplo.Los diseñadores de .NET framework han seguido este patrón, siendo buenos ejemplos el BitConverter
, BinaryReader
y Convert
clases.
String
representa System.String
y es un tipo .NET Framework. string
es un alias en el lenguaje C# para System.String
.Ambos están compilados para System.String
en IL (Lenguaje Intermedio), por lo que no hay diferencia.Elige lo que te guste y úsalo.Si codificas en C#, preferiría string
ya que es un alias de tipo C# y muy conocido por los programadores de C#.
Puedo decir lo mismo sobre (int
, System.Int32
) etc..
La mejor respuesta que he escuchado sobre el uso de los alias de tipo proporcionados en C# proviene de Jeffrey Richter en su libro. CLR a través de C#.Aquí están sus 3 razones:
- He visto a varios desarrolladores confundidos, sin saber si usar cadena o Cadena en su código.Debido a que en C# la cadena (una palabra clave) se asigna exactamente a System.String (un tipo FCL), no hay diferencia y se puede usar cualquiera de las dos.
- Cª#, largo mapas para Sistema.Int64, pero en un lenguaje de programación diferente, largo podría mapear a un Int16 o Int32.De hecho, C++/CLI trata a long como un Int32.Alguien que lea el código fuente en un idioma podría fácilmente malinterpretar la intención del código si estuviera acostumbrado a programar en un lenguaje de programación diferente.De hecho, la mayoría de los idiomas ni siquiera tratan largo como palabra clave y no compilará el código que la utilice.
- La FCL tiene muchos métodos que tienen nombres de tipo como parte de sus nombres de método.Por ejemplo, el Lector binario type ofrece métodos como Leer booleano, LeerInt32, LeerSingle, y así sucesivamente, y el Sistema.Convertir type ofrece métodos como a booleano, AInt32, Parasoltero, etcétera.Aunque es legal escribir el siguiente código, la línea con float me parece muy antinatural y no es obvio que la línea sea correcta:
BinaryReader br = new BinaryReader(...);
float val = br.ReadSingle(); // OK, but feels unnatural
Single val = br.ReadSingle(); // OK and feels good
Ahí lo tienes.Creo que todos estos son puntos realmente buenos.Sin embargo, no uso los consejos de Jeffrey en mi propio código.Tal vez estoy demasiado atrapado en mi mundo C# pero termino intentando que mi código se parezca al código del marco.
string
es una palabra reservada, pero String
es solo un nombre de clase.Esto significa que string
no se puede utilizar como nombre de variable por sí solo.
Si por alguna razón quisieras una variable llamada cadena, verás sólo la primera de estas compilaciones:
StringBuilder String = new StringBuilder(); // compiles
StringBuilder string = new StringBuilder(); // doesn't compile
Si realmente quieres un nombre de variable llamado cadena puedes usar @
como prefijo:
StringBuilder @string = new StringBuilder();
Otra diferencia crítica:Stack Overflow los resalta de manera diferente.
Hay una diferencia - no puedes usar String
sin using System;
antemano.
Ha sido cubierto arriba;sin embargo, no puedes usar string
en reflexión;debes usar String
.
System.String
es la clase de cadena .NET - en C# string
es un alias para System.String
- entonces en uso son iguales.
En cuanto a las pautas, no me estancaría demasiado y simplemente usaría lo que quisiera: hay cosas más importantes en la vida y el código será el mismo de todos modos.
Si se encuentran construyendo sistemas donde es necesario especificar el tamaño de los números enteros que están usando y por lo tanto tienden a usar Int16
, Int32
, UInt16
, UInt32
etc.entonces podría parecer más natural de usar String
- y al moverme entre diferentes lenguajes .net, podría hacer que las cosas sean más comprensibles; de lo contrario, usaría string e int.
prefiero las mayusculas .NET
tipos (en lugar de alias) por motivos de formato.El .NET
Los tipos tienen el mismo color que otros tipos de objetos (después de todo, los tipos de valores son objetos adecuados).
Palabras clave condicionales y de control (como if
, switch
, y return
) están en minúsculas y son de color azul oscuro (de forma predeterminada).Y preferiría no tener desacuerdos sobre el uso y el formato.
Considerar:
String someString;
string anotherString;
string
y String
son idénticos en todos los sentidos (excepto la "S" mayúscula).No hay implicaciones de rendimiento de ninguna manera.
Minúsculas string
Se prefiere en la mayoría de los proyectos debido al resaltado de sintaxis.
C# es un lenguaje que se utiliza junto con CLR.
string
es un tipo en C#.
System.String
es un tipo en el CLR.
Cuando usas C# junto con CLR string
será mapeado a System.String
.
En teoría, podría implementar un compilador de C# que generara código de bytes de Java.Una implementación sensata de este compilador probablemente mapearía string
a java.lang.String
para interoperar con la biblioteca de tiempo de ejecución de Java.
este youtube El vídeo demuestra prácticamente en qué se diferencian.
Pero ahora una larga respuesta textual.
cuando hablamos de .NET
hay dos cosas diferentes una hay .NET
framework y el otro hay lenguajes ( C#
, VB.NET
etc) que utilizan ese marco.
"System.String
" también conocido como "Cadena" ( "S mayúscula") es un .NET
tipo de datos del marco, mientras que "cadena" es un C#
tipo de datos.
En resumen, "Cadena" es un alias (lo mismo llamado con nombres diferentes) de "cadena".Entonces, técnicamente, las dos declaraciones de código siguientes darán el mismo resultado.
String s = "I am String";
o
string s = "I am String";
De la misma manera, existen alias para otros tipos de datos de C#, como se muestra a continuación:
objeto: System.Object
, cadena: System.String
, booleano: System.Boolean
, byte: System.Byte
, sbyte: System.SByte
, corto: System.Int16
etcétera
Ahora la pregunta del millón desde el punto de vista del programador. Entonces, ¿cuándo usar "String" y "string"?
Lo primero para evitar confusiones es utilizar uno de ellos de forma constante.Pero desde la perspectiva de las mejores prácticas, cuando realiza una declaración de variables, es bueno usar "cadena" (pequeña "s") y cuando la usa como nombre de clase, entonces se prefiere "Cadena" (mayúscula "S").
En el siguiente código, el lado izquierdo es una declaración de variable y se declara usando "cadena".En el lado derecho llamamos a un método, por lo que "Cadena" es más sensato.
string s = String.ToUpper() ;
Minúscula string
es un alias para System.String
.son iguales en C#
.
Existe un debate sobre si se deben utilizar los tipos de sistema (System.Int32
, System.String
, etc.) tipos o el C# aliases
(int
, string
, etc).Personalmente creo que deberías usar el C# aliases
, pero esa es solo mi preferencia personal.
string
es solo un alias para System.String
.El compilador los tratará de manera idéntica.
La única diferencia práctica es el resaltado de sintaxis como mencionas, y que tienes que escribir using System
si utiliza String
.
Ambos son lo mismo.Pero desde la perspectiva de las pautas de codificación, es mejor usar string
en lugar de String
.Esto es lo que generalmente usan los desarrolladores.p.ej.En lugar de usar Int32
usamos int
como int
es alias de Int32
FYI “La cadena de palabras clave es simplemente un alias para la clase predefinida System.String
. " - C# Especificación del idioma 4.2.3http://msdn2.microsoft.com/En-US/library/aa691153.aspx
Como dicen los demás, son iguales.Las reglas de StyleCop, de forma predeterminada, le obligarán a utilizar string
como práctica recomendada de estilo de código C#, excepto cuando se hace referencia System.String
funciones estáticas, como String.Format
, String.Join
, String.Concat
, etc...
Nueva respuesta después de 6 años y 5 meses (procrastinación).
Mientras string
es una palabra clave reservada de C# que siempre tiene un significado fijo, String
es solo algo ordinario identificador que podría referirse a cualquier cosa.Dependiendo de los miembros del tipo actual, el espacio de nombres actual y el aplicado using
directivas y su ubicación, String
podría ser un valor o un tipo distinto de global::System.String
.
Proporcionaré dos ejemplos en los que using
las directivas no ayudarán.
Primero, cuando String
es un valor del tipo actual (o una variable local):
class MySequence<TElement>
{
public IEnumerable<TElement> String { get; set; }
void Example()
{
var test = String.Format("Hello {0}.", DateTime.Today.DayOfWeek);
}
}
Lo anterior no se compilará porque IEnumerable<>
no tiene un miembro no estático llamado Format
, y no se aplican métodos de extensión.En el caso anterior, todavía es posible utilizar String
en otros contextos donde tipo es la única posibilidad sintácticamente.Por ejemplo String local = "Hi mum!";
podría estar bien (dependiendo del espacio de nombres y using
directivas).
Peor:Dicho String.Concat(someSequence)
probablemente (dependiendo de using
s) vaya al método de extensión Linq Enumerable.Concat
.No irá al método estático. string.Concat
.
En segundo lugar, cuando String
es otro tipo, anidado dentro del tipo actual:
class MyPiano
{
protected class String
{
}
void Example()
{
var test1 = String.Format("Hello {0}.", DateTime.Today.DayOfWeek);
String test2 = "Goodbye";
}
}
Ninguna declaración en el Example
El método compila.Aquí String
siempre es un piano cadena, MyPiano.String
.Ningún miembro (static
O no) Format
existe en él (o se hereda de su clase base).y el valor "Goodbye"
no se puede convertir en él.
El uso de tipos de sistema facilita la transferencia entre C# y VB.Net, si le gustan ese tipo de cosas.
Contra lo que parece ser una práctica común entre otros programadores, prefiero String
encima string
, sólo para resaltar el hecho de que String
es un tipo de referencia, como mencionó Jon Skeet.
string
es un alias (o taquigrafía) de System.String
.Eso significa que al escribir string
queríamos decir System.String
.Puedes leer más en el enlace think: 'cadena' es un alias/taquigrafía de System.String.
Cadena (System.String
) es una clase en la biblioteca de clases base.string (minúscula) es un trabajo reservado en C# que es un alias para System.String.Int32 vs int es una situación similar a la actual Boolean vs. bool
.Estas palabras clave específicas del lenguaje C# le permiten declarar primitivas en un estilo similar a C.
Solo me gustaría agregar esto a la respuesta de Loust, del libro de Ritchers:
La especificación del idioma C# establece: "Como cuestión de estilo, el uso de la palabra clave se favorece sobre el uso del nombre completo del tipo de sistema". No estoy de acuerdo con la especificación del idioma;Prefiero usar los nombres de tipo FCL y evitar completamente los nombres de tipo primitivo.De hecho, desearía que los compiladores ni siquiera ofrecieran los nombres de tipo primitivo y los desarrolladores forzados a usar los nombres de tipo FCL.Aquí están mis razones:
He visto a varios desarrolladores confundidos, sin saber si usar cadenao Cadena en su código.Porque en C# cadena (una palabra clave) se asigna exactamente a Sistema.Cadena (un tipo FCL), no hay diferencia y se puede utilizar cualquiera de los dos.Del mismo modo, he escuchado a algunos desarrolladores decir que En t representa un entero de 32 bits cuando la aplicación se ejecuta en un sistema operativo de 32 bits y que representa un entero de 64 bits cuando la aplicación se ejecuta en un sistema operativo de 64 bits.Esta afirmación es absolutamente falsa:en C#, un En t siempre mapas para Sistema.Int32, y, por lo tanto, representa un entero de 32 bits, independientemente del sistema operativo, el código se ejecuta.Si los programadores usaran Int32 En su código, entonces esta posible confusión también se elimina.
Cª#, largo mapas para Sistema.Int64, pero en un lenguaje de programación diferente, largopodría mapear a un Int16 o Int32.De hecho, C++/CLI trata largo como un Int32.Alguien que lea el código fuente en un idioma podría malinterpretar fácilmente la intención del código si él o ella estuvieran acostumbrados a programar en un lenguaje de programación diferente.De hecho, la mayoría de los idiomas ni siquiera tratan largo Como palabra clave y no compilará un código que lo use.
La FCL tiene muchos métodos que tienen nombres de tipo como parte de sus nombres de método.Por ejemplo, el Lector binario type ofrece métodos como Leer booleano, LeerInt32, LeerSingle, y así sucesivamente, y el Sistema.Convertir type ofrece métodos como a booleano, AInt32, Parasoltero, etcétera.Aunque es legal escribir el siguiente código, la línea con flotar Se siente muy antinatural para mí, y no es obvio que la línea sea correcta:
BinaryReader br = new BinaryReader(...); float val = br.ReadSingle(); // OK, but feels unnatural Single val = br.ReadSingle(); // OK and feels good
Muchos programadores que usan C# tienden exclusivamente a olvidar que otros lenguajes de programación se pueden usar contra el CLR, y debido a esto, los c# -ismos se arrastran en el código de la biblioteca de clases.Por ejemplo, el FCL de Microsoft está escrito casi exclusivamente en C# y los desarrolladores del equipo de FCL ahora han introducido métodos en la biblioteca, como Formación's ObtenerLongitudLongitud, que devuelve un Int64 valor que es un largo en C# pero no en otros idiomas (como C ++/CLI).Otro ejemplo es System.Linq.Enumerable's Cuenta larga método.
No obtuve su opinión antes de leer el párrafo completo.
String
no es una palabra clave y puede usarse como identificador, mientras que string
es una palabra clave y no se puede utilizar como identificador.Y desde el punto de vista funcional, ambos son iguales.
Llegar tarde a la fiesta:Utilizo los tipos CLR el 100% del tiempo (bueno, excepto si forzado usar el tipo C#, pero no recuerdo cuándo fue la última vez).
Originalmente comencé a hacer esto hace años, según los libros CLR de Ritchie.Para mí tenía sentido que, en última instancia, todos los lenguajes CLR tuvieran que ser capaces de admitir el conjunto de tipos CLR, por lo que utilizar los tipos CLR usted mismo proporcionaba un código más claro y posiblemente más "reutilizable".
Ahora que lo hago desde hace años, es un hábito y me gusta la coloración que muestra VS para los tipos CLR.
La única verdadera decepción es que la función de autocompletar utiliza el tipo C#, por lo que termino volviendo a escribir los tipos generados automáticamente para especificar el tipo CLR.
Además, ahora, cuando veo "int" o "string", me parece muy incorrecto, como si estuviera mirando el código C de los años 70.
En realidad, es una cuestión de convención. string
simplemente se parece más al estilo C/C++.La convención general es utilizar cualquier atajo que haya proporcionado el idioma elegido (int/Int para Int32
).Esto se aplica a "objeto" y decimal
también.
En teoría, esto podría ayudar a portar el código a algún estándar futuro de 64 bits en el que "int" podría significar Int64
, pero ese no es el punto, y esperaría que cualquier asistente de actualización cambiara cualquier int
referencia a Int32
de todos modos solo para estar seguro.
No hay diferencia.
La palabra clave C# string
se asigna al tipo .NET System.String
- es un alias que respeta las convenciones de nomenclatura del idioma.
Similarmente, int
mapas para System.Int32
.
Hay una cita sobre este tema de El libro de Daniel Solís..
Todos los tipos predefinidos se asignan directamente a los tipos de .NET subyacentes.Los nombres de tipo C# (String) son simplemente alias para los tipos de .NET (String o System.String), por lo que el uso de los nombres de .NET funciona bien sintácticamente, aunque esto se desalienta.Dentro de un programa C#, debe usar los nombres C# en lugar de los nombres .NET.
cadena es una palabra clave y no puede utilizar una cadena como identificador.
Cadena no es una palabra clave y puedes usarla como identificador:
Ejemplo
string String = "I am a string";
La palabra clave string
es un alias para System.String
Además del problema de las palabras clave, los dos son exactamente equivalentes.
typeof(string) == typeof(String) == typeof(System.String)
Sí, esa no es la diferencia entre ellos, al igual que el bool
y Boolean
.
No hay diferencia entre los dos - string
, sin embargo, parece ser la opción preferida al considerar el código fuente de otros desarrolladores.