c# - ¿Cuál es la diferencia entre String y string en C #?


Ejemplo ( observe el caso ):

string s = "Hello world!";
String S = "Hello world!";

¿Cuáles son las pautas para el uso de cada uno? Y cuales son las diferencias?



Answers



string es un alias en C # para System.String . Entonces, técnicamente, no hay diferencia. Es como int vs. System.Int32 .

En cuanto a las pautas, creo que en general se recomienda usar string cada vez que se refiera a un objeto.

p.ej

string place = "world";

Del mismo modo, creo que generalmente se recomienda usar String si necesita referirse específicamente a la clase.

p.ej

string greet = String.Format("Hello {0}!", place);

Este es el estilo que Microsoft tiende a usar en sus ejemplos .

Parece que la orientación en esta área puede haber cambiado, ya que StyleCop ahora impone el uso de los alias específicos de C #.




Solo para completar, aquí hay un montón de información relacionada ...

Como otros han notado, string es un alias para System.String . Compilan con el mismo código, por lo que en el momento de la ejecución no hay diferencia alguna. Este es solo 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

Además de string , object , los alias son todos tipos de valores. decimal es un tipo de valor, pero no un tipo primitivo en el CLR. El único tipo primitivo que no tiene un alias es System.IntPtr .

En la especificación, los alias de tipo de valor se conocen como "tipos simples". Los literales se pueden usar para valores constantes de todos los tipos simples; ningún otro tipo de valor tiene formas literales disponibles. (Compare esto con VB, que permite literales DateTime , y también tiene un alias).

Hay una circunstancia en la que debe 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

Esa es solo una cuestión de la forma en que la especificación define las declaraciones enum: la parte después de los dos puntos debe ser la producción de tipo integral , que es una ficha de sbyte , byte , short , ushort , int , uint , long , ulong , char . .. a diferencia de una producción de tipo utilizada por declaraciones variables, por ejemplo. No indica ninguna otra diferencia.

Finalmente, cuando se trata de usar: personalmente utilizo los alias en todas partes para la implementación, pero el tipo CLR para cualquier API. Realmente no importa demasiado lo que usas en términos de implementación: la consistencia entre tu equipo es agradable, pero a nadie más le va a importar. Por otro lado, es realmente importante que si te refieres a un tipo en una API, lo hagas de forma neutral en cuanto al idioma. Un método llamado ReadInt32 no es ambiguo, mientras que un método llamado ReadInt requiere interpretación. La persona que llama podría estar usando un lenguaje que define un alias int para Int16 , por ejemplo. Los diseñadores de .NET Framework han seguido este patrón, buenos ejemplos están en las BitConverter , BinaryReader y Convert .




String significa System.String y es un tipo de .NET Framework. string es un alias en el lenguaje C # para System.String . Ambos están compilados en System.String en IL (lenguaje intermedio), por lo que no hay diferencia. Elige lo que te gusta y usa eso. Si codifica en C #, prefiero string porque es un alias de tipo C # y es 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 alias de tipo proporcionado en C # proviene de Jeffrey Richter en su libro CLR Via C # . Aquí están sus 3 razones:

  • He visto a varios desarrolladores confundidos, sin saber si usar cadena o cadena en su código. Como en C #, la cadena (una palabra clave) se correlaciona exactamente con System.String (un tipo FCL), no hay diferencia y puede usarse.
  • En C #, los mapas largos a System.Int64 , pero en un lenguaje de programación diferente, long se puede asignar a un Int16 o Int32 . De hecho, C ++ / CLI de hecho trata como Int32 . Alguien que lea el código fuente en un idioma podría malinterpretar fácilmente 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 tratarán como una palabra clave y no compilarán el código que la usa.
  • La FCL tiene muchos métodos que tienen nombres de tipos como parte de sus nombres de métodos. Por ejemplo, el tipo BinaryReader ofrece métodos como ReadBoolean , ReadInt32 , ReadSingle , etc., y el tipo System.Convert ofrece métodos como ToBoolean , ToInt32 , ToSingle , etc. Aunque es legal escribir el siguiente código, la línea con flotador 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

Entonces ahí lo tienes. Creo que estos son todos puntos realmente buenos. Sin embargo, no encuentro el consejo de Jeffrey en mi propio código. Tal vez estoy demasiado atrapado en mi mundo C # pero termino tratando de hacer que mi código se vea como el código de framework.




string es una palabra reservada, pero String es solo un nombre de clase. Esto significa que la string no se puede usar como un nombre de variable por sí mismo.

Si por alguna razón quieres una variable llamada cadena , solo verías la primera de estas compilaciones:

StringBuilder String = new StringBuilder();  // compiles
StringBuilder string = new StringBuilder();  // doesn't compile 

Si realmente quiere un nombre de variable llamado cadena , puede usar @ como prefijo:

StringBuilder @string = new StringBuilder();

Otra diferencia fundamental: el desbordamiento de la pila los resalta de manera diferente.




Hay una diferencia : no puede usar String sin using System; antemano.




Ha sido cubierto arriba; sin embargo, no puedes usar string en la reflexión; debes usar String .




Valters, no se pueden establecer alias globales en el estilo de string , int , etc. hasta donde yo sé. Sin embargo, puede hacer más alias localizados para tipos y espacios de nombres con la palabra clave using .

p.ej

using str = System.String;
using strDict = System.Collections.Generic.Dictionary<string, string>;
//...
str s = "Now you've got another alias for string!";
var d = new strDict();

Ver aquí: uso de la Directiva (Referencia C #)




System.String es la clase de cadena .net - en C # string es un alias para System.String - por lo que en uso son los mismos.

En cuanto a las pautas, no me atascaría demasiado y solo 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 enteros que están usando y tienden a utilizar Int16 , Int32 , UInt16 , UInt32 , etc., podría parecer más natural usar String , y cuando se mueven entre diferentes .net podría hacer las cosas más comprensibles; de lo contrario, usaría string e int.




string y String son idénticos en todos los sentidos (excepto en mayúscula "S"). No hay implicaciones de rendimiento de ninguna manera.

La string minúscula es preferida en la mayoría de los proyectos debido al resaltado de sintaxis




Prefiero los tipos .NET mayúsculas (en lugar de los alias) por razones de formato. Los tipos de .NET tienen el mismo color que otros tipos de objetos (después de todo, los tipos de valores son objetos adecuados).

Las palabras clave condicionales y de control (como if , switch y return ) son minúsculas y de color azul oscuro (de forma predeterminada). Y preferiría no tener el desacuerdo en uso y formato.

Considerar:

String someString; 
string anotherString; 



C # es un lenguaje que se usa junto con el CLR.

string es un tipo en C #.

System.String es un tipo en el CLR.

Cuando usa C # junto con CLR, la string se asignará a System.String .

Teóricamente, podría implementar un compilador de C # que generara bytecode de Java. Una implementación sensata de este compilador probablemente correlacionaría la string con java.lang.String para interoperar con la biblioteca de tiempo de ejecución de Java.




Este video de YouTube demuestra prácticamente cómo difieren.

Pero ahora para una larga respuesta textual.

Cuando hablamos de .NET hay dos cosas diferentes: una es .NET framework y la otra hay idiomas ( C# , VB.NET , etc.) que usan esa infraestructura.

" System.String " también conocido como "String" (mayúscula "S") es un tipo de datos de .NET framework, mientras que "string" es un tipo de datos C# .

En resumen, "String" es un alias (lo mismo que se llama con diferentes nombres) de "cadena". Entonces, técnicamente, tanto las declaraciones de código a continuación darán el mismo resultado.

String s = "I am String";

o

string s = "I am String";

Del mismo modo, existen alias para otros tipos de datos c # como se muestra a continuación:

objeto: System.Object , string: System.String , bool: System.Boolean , byte: System.Byte , sbyte: System.SByte , short: System.Int16 y así sucesivamente

Ahora, la pregunta del millón desde el punto de vista del programador ¿Cuándo utilizar "Cadena" y "cadena"?

Lo primero que debe hacer para evitar confusiones es usar uno de ellos consistentemente. Pero desde la perspectiva de las mejores prácticas cuando haces una declaración de variables, es bueno usar "cadena" ("s" pequeña) y cuando la utilizas como nombre de clase, se prefiere "Cadena" ("S" mayúscula).

En el siguiente código, el lado izquierdo es una declaración de variable y se declara usando "cadena". En el lado derecho estamos llamando a un método, por lo que "Cadena" es más sensato.

string s = String.ToUpper() ;



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 usted menciona, y que debe escribir using System si usa String .




La string minúscula es un alias para System.String . Son lo mismo en C# .

Existe un debate sobre si debe usar los tipos de Sistema ( System.Int32 , System.String , etc.) o los C# aliases ( int , string , etc.). Personalmente creo que debes usar los C# aliases , pero esa es solo mi preferencia personal.




Ambos son lo mismo. Pero desde la perspectiva de las pautas de codificación, es mejor usar string lugar de String . Esto es lo que generalmente utilizan los desarrolladores. por ejemplo, en lugar de usar Int32 usamos int como int es alias para Int32

FYI "La cadena de palabra clave es simplemente un alias para la clase predefinida System.String ". - C # Language Specification 4.2.3 http://msdn2.microsoft.com/En-US/library/aa691153.aspx




Como los otros dicen, son lo mismo. Las reglas de StyleCop, de forma predeterminada, le obligarán a utilizar string como una práctica recomendada de estilo de código C #, excepto cuando se hace referencia a funciones estáticas de System.String , como String.Format , String.Join , String.Concat , etc ...




El uso de tipos de sistema facilita el puerto entre C # y VB.Net, si te gusta este tipo de cosas.




Contra lo que parece ser una práctica común entre otros programadores, prefiero String a string , solo para resaltar el hecho de que String es un tipo de referencia, como mencionó Jon Skeet.







String ( System.String ) es una clase en la biblioteca de la clase 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 Boolean vs. bool . Estas palabras clave específicas del lenguaje C # le permiten declarar primitivas en un estilo similar a C.




String no es una palabra clave y puede usarse como identificador, mientras que string es una palabra clave y no puede usarse como identificador. Y en el punto de vista de la función, ambos son iguales.




Llegando tarde a la fiesta: utilizo los tipos de CLR el 100% del tiempo (bueno, excepto si me veo obligado a usar el tipo de 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í, tiene sentido que todos los lenguajes CLR finalmente tengan que ser compatibles con el conjunto de tipos de CLR, por lo que el uso de los tipos de CLR usted mismo proporciona un código más claro y posiblemente más "reutilizable".

Ahora que lo he estado haciendo durante años, es un hábito y me gusta la coloración que VS muestra para los tipos de CLR.

La única desventaja real es que el autocompletado usa el tipo C #, por lo que termino escribiendo de nuevo los tipos generados automáticamente para especificar el tipo CLR.

Además, ahora, cuando veo "int" o "cadena", me parece realmente incorrecto, como si estuviera viendo el código C de 1970.




Me gustaría agregar esto a la respuesta de lfousts, del libro de Ritchers:

La especificación del lenguaje C # establece: "Como cuestión de estilo, se prefiere el uso de la palabra clave 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 por completo los nombres de tipos primitivos. De hecho, me gustaría que los compiladores ni siquiera ofrecieran los nombres de tipos primitivos y obligaran a los desarrolladores a usar los nombres de tipos de FCL. Aquí están mis razones:

No obtuve su opinión antes de leer el párrafo completo.




Es una cuestión de convención, realmente. "cadena" simplemente se parece más al estilo C / C ++. La convención general es utilizar los accesos directos que haya proporcionado el idioma elegido (int / Int para Int32). Esto va para el "objeto" y "decimal" también.

En teoría, esto podría ayudar a código de puerto en un futuro estándar de 64 bits en el que "int" podría significar Int64, pero ese no es el punto, y yo esperaría que cualquier asistente de actualización para cambiar todas las referencias "int" a "Int32" de todos modos sólo a cuidate.




No hay diferencia.

La palabra clave de C # stringasigna al tipo .NET System.String- es un alias que mantiene a los convenios de denominación de la lengua.

Del mismo modo, intse asigna a System.Int32.




Nueva respuesta después de 6 años y 5 meses (dilación).

Si bien stringes una palabra clave reservada de C # que siempre tiene un significado fijo, Stringes sólo un ordinario identificador que podría referirse a cualquier cosa. Dependiendo de los miembros del tipo actual, el espacio de nombres actual y las aplicadas usingdirectivas y su colocación, Stringpodría ser un valor o un tipo distinto de global::System.String.

I presentará dos ejemplos en los que usinglas directivas no ayudarán .

En primer lugar, cuando Stringes un valor del tipo de corriente (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 compilará porque IEnumerable<>no tiene un miembro no estática llama Format, y no aplicar los métodos de extensión. En el caso anterior, todavía puede ser posible utilizar Stringen otros contextos en los que un tipo es la única posibilidad sintácticamente. Por ejemplo String local = "Hi mum!";podría estar bien (dependiendo del espacio de nombres y usingdirectivas).

Peor aún: el decir String.Concat(someSequence)probablemente (dependiendo usings) vaya al método de extensión de LINQ Enumerable.Concat. No va a ir al método estático string.Concat.

En segundo lugar, cuando Stringes otro tipo , anidado dentro del tipo de corriente:

class MyPiano
{
  protected class String
  {
  }

  void Example()
  {
    var test1 = String.Format("Hello {0}.", DateTime.Today.DayOfWeek);
    String test2 = "Goodbye";
  }
}

Ninguna de estas afirmaciones en el Examplemétodo compila. Aquí Stringes siempre un piano cadena , MyPiano.String. Ningún miembro ( statico no) Formatexiste en él (o se hereda de su clase base). Y el valor "Goodbye"no se puede convertir en ella.




Sí, eso es ninguna diferencia entre ellos, al igual que el boole Boolean.




cadena es una palabra clave, y no se puede utilizar la cadena como identificador.

Cadena no es una palabra clave, y se puede usar como un identificador:

Ejemplo

string String = "I am a string";

La palabra clave stringes un alias para System.Stringaparte de la cuestión de palabras clave, los dos son exactamente equivalentes.

 typeof(string) == typeof(String) == typeof(System.String)



Hay una cita en este tema desde el libro Daniel Solis .

Todos los tipos predefinidos se asignan directamente a los tipos de .NET subyacentes. Los nombres de tipo C # (cuerda) 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 no se recomienda. Dentro de un programa en C #, debe utilizar los nombres de C # en lugar de los nombres de .NET.