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

6995

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?

9
  • 89
    @ORMapper, pero el hecho es que stringes una construcción léxica de la gramática C # mientras que System.Stringes solo un tipo. Independientemente de cualquier diferencia explícita mencionada en cualquier especificación, todavía existe esta diferencia implícita que podría acomodarse con cierta ambigüedad. El lenguaje en sí debe ser compatible stringde una manera que la implementación no esté (del todo) tan obligada a considerar para una clase particular en BCL. 2 dic 14 a las 3:05
  • 123
    @KirkWoll: De acuerdo con la especificación del idioma, el idioma en sí debe considerarse stringexactamente el mismo que el tipo BCL System.String, nada más. Eso no es ambiguo en absoluto. Por supuesto, puede implementar su propio compilador, usando la gramática C #, y usar todos los tokens encontrados así para algo arbitrario, no relacionado con lo que se define en la especificación del lenguaje C #. Sin embargo, el lenguaje resultante solo sería similar a C #, no podría considerarse C #. 2 de diciembre de 2014 a las 8:22
  • 103
    Puede usar stringsin una directiva using para System. No puedes hacer eso con String.
    Wilsu
    30 de noviembre de 2015 a las 8:52
  • 17
    Para alguien que viene de Algol y Fortran, esta discusión muestra que hay algo mal en string. Es necesario abreviar System.String, pero, como alias, parece bastante, pero no exactamente lo mismo. Después de varios años de C #, sin embargo, yo diría, es seguro de usar, simplemente stringy string.Format()no que preocuparse por System.String.
    Roland
    20/12/2016 a las 0:24
  • 12
    @Sangeeta ¿Qué estás diciendo? La System.Stringclase todavía está allí y la stringpalabra clave sigue siendo un alias para ella. Al igual que System.Int32y int. Son literalmente lo mismo. 8 de diciembre de 2018 a las 2:14
6569

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

En cuanto a las pautas, generalmente se recomienda usar stringcada vez que se refiera a un objeto.

p.ej

string place = "world";

Del mismo modo, creo que generalmente se recomienda usarlo Stringsi necesita hacer referencia específicamente a la clase.

p.ej

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

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

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

7
  • 177
    Si decide usar StyleCop y sigue eso, eso dirá que use los tipos específicos del idioma. Entonces, para C # tendrá string (en lugar de String), int (en lugar de Int32), float (en lugar de Single) - stylecop.soyuz5.com/SA1121.html 22 de mayo de 2012 a las 22:36
  • 163
    Siempre uso los alias porque asumí que algún día podría ser útil porque actúan como una abstracción, por lo que pueden cambiar sus implementaciones sin que yo lo sepa.
    Rob
    12/10/12 a las 23:25
  • 46
    Visual Studio 2015 dice que String.Format debería cambiarse a string.Format, así que supongo que Microsoft va por ese camino. También siempre he usado String para los métodos estáticos. 22 de diciembre de 2014 a las 5:21
  • ¿Qué le dice al hecho de que podría definir su propio tipo "Cadena" pero no puede hacer lo mismo con "cadena", ya que es una palabra clave, como se explica en stackoverflow.com/questions/7074/…?
    jmoreno
    13/10/20 a las 21:37
  • Supongo que entonces ... Solo sé coherente. Use string o String o use un cerntain one en un caso específico, pero siempre en ese caso.
    Rob L
    29 nov.20 a las 6:50
3639

Solo en aras de la integridad, aquí hay un volcado de información relacionada con el cerebro ...

Como han señalado otros, stringes un alias de System.String. Suponiendo que su código using se Stringcompila System.String(es decir, no tiene una directiva using para algún otro espacio de nombres con un Stringtipo diferente ), se compilan en 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

Aparte de stringy object, los alias son todos para tipos de valor. decimales 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 tipo de valor 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 DateTimeliterales y también tiene un alias).

Hay una circunstancia en la que se tiene que utilizar 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 la especificación define los enumeración declaraciones - la parte después de los dos puntos tiene que ser el de tipo integral de producción, que es una muestra de sbyte, byte, short, ushort, int, uint, long, ulong, char... en lugar de un tipo de producción, utilizado por 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 use en términos de implementación: la consistencia entre su equipo es buena, pero a nadie más le va a importar. Por otro lado, es realmente importante que si hace referencia a un tipo en una API, lo haga de una manera neutral en cuanto al lenguaje. Un método llamado ReadInt32es inequívoco, mientras que un método llamado ReadIntrequiere interpretación. La persona que llama podría estar usando un idioma que defina un intalias para Int16, por ejemplo. Los diseñadores marco .NET han seguido este patrón, buenos ejemplos de estar en las BitConverter, BinaryReadery Convertlas clases.

0
771

Stringsignifica System.Stringy es un tipo .NET Framework. stringes un alias en el lenguaje C # para System.String. Ambos están compilados System.Stringen IL (Intermediate Language), por lo que no hay diferencia. Elija lo que le guste y úselo. Si codifica en C #, preferiría stringya que es un alias de tipo C # y es bien conocido por los programadores de C #.

Puedo decir lo mismo sobre ( int, System.Int32) etc.

5
  • 7
    Personalmente prefiero usar "Int32", ya que muestra inmediatamente el rango del valor. Imagínese si actualizaran el tipo de "int" en sistemas posteriores de bits superiores. 'int' en c aparentemente se ve como "el tipo de entero con el que el procesador de destino trabaja más eficientemente" , y se define como "al menos 16 bits". Preferiría una consistencia predecible allí, muchas gracias. 28/04/2016 a las 11:41
  • 4
    @MyDaftQuestions Estoy de acuerdo. En todo caso, tendría sentido usar consistentemente los tipos .net porque ignoran el idioma y el tipo es obvio, independiente de cualquier idioma (¿conozco todas las idiosincrasias de F # o VB?). 21/01/2017 a las 17:39
  • 12
    @Nyerguds Hay dos razones para simplemente no preocuparse por eso. Una es que intse define en la especificación del lenguaje C # como un entero de 32 bits independientemente del hardware. C #, a pesar de una herencia compartida en la noche de los tiempos, en realidad no es C. Cambiar inta un entero de 64 bits sería un cambio radical en la especificación y el lenguaje. También sería necesario redefinirlo long, como longes actualmente el entero de 64 bits. La otra razón para no preocuparse es irrelevante ya que los tipos nunca cambiarán, pero .NET es lo suficientemente abstracto como para que el 99% del tiempo no tenga que pensar en ello de todos modos. ;-) 8 de diciembre de 2018 a las 2:47
  • 8
    @Craig cavo en lotes de formatos de juego de propiedad de edad en la que no tengo que pensar en eso todo el tiempo, sin embargo. Y luego usar Int16, Int32y Int64es mucho más transparente en el código que usar el bastante no descriptivo short, intylong 9 de diciembre de 2018 a las 2:29
  • 3
    Pero short, not, long, float, double, et al son descriptivos, porque están en la especificación del lenguaje. C # no es C. Los prefiero en las declaraciones porque son concisos, pequeños y estéticamente agradables. Prefiero los nombres de la biblioteca Torre en las API donde la API tiene una dependencia del tipo de datos. 14/10/20 a las 15:49
544

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 Via C # . Estas son sus 3 razones:

  • I've seen a number of developers confused, not knowing whether to use string or String in their code. Because in C# the string (a keyword) maps exactly to System.String (an FCL type), there is no difference and either can be used.
  • In C#, long maps to System.Int64, but in a different programming language, long could map to an Int16 or Int32. In fact, C++/CLI does in fact treat long as an Int32. Someone reading source code in one language could easily misinterpret the code's intention if he or she were used to programming in a different programming language. In fact, most languages won't even treat long as a keyword and won't compile code that uses it.
  • The FCL has many methods that have type names as part of their method names. For example, the BinaryReader type offers methods such as ReadBoolean, ReadInt32, ReadSingle, and so on, and the System.Convert type offers methods such as ToBoolean, ToInt32, ToSingle, and so on. Although it's legal to write the following code, the line with float feels very unnatural to me, and it's not obvious that the line is correct:
BinaryReader br = new BinaryReader(...);
float val  = br.ReadSingle(); // OK, but feels unnatural
Single val = br.ReadSingle(); // OK and feels good

Así que ahí lo tienes. Creo que todos estos son puntos realmente buenos. Sin embargo, no me encuentro usando los consejos 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 parezca al código del marco.

0
487

stringes una palabra reservada, pero Stringes solo un nombre de clase. Esto significa que stringno se puede utilizar como nombre de variable por sí solo.

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

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

Si realmente desea un nombre de variable llamado cadena , puede usarlo @como prefijo:

StringBuilder @string = new StringBuilder();

Otra diferencia crítica: Stack Overflow los resalta de manera diferente.

0
426

Hay una diferencia : no se puede usar Stringsin using System;antes.

0
333

Ha sido cubierto arriba; sin embargo, no se puede utilizar stringen la reflexión; debe usar String.

1
  • 15
    No entiendo qué significa esta respuesta y por qué se votó a favor. Puedes usarlo typeof(string)en la reflexión. Ejemplo uno: if (someMethodInfo.ReturnType == typeof(string)) { ... }Ejemplo dos: var p = typeof(string).GetProperty("FirstChar", BindingFlags.NonPublic | BindingFlags.Instance);¿Dónde debe usarlo String, no string? Si prueba cosas como Type.GetType("String")o Type.GetType("string"), ninguno encontrará la clase porque falta el espacio de nombres. Si por alguna tonta razón compara .Nameun tipo con el "string"que distingue entre mayúsculas y minúsculas, tiene razón. 24 de mayo de 2019 a las 12:04
285

System.Stringes la clase de cadena .NET; en C # stringes un alias para System.String, por lo que en uso son lo mismo.

En cuanto a las pautas, no me atascaría demasiado y solo usaría lo que quiera: hay cosas más importantes en la vida y el código será el mismo de todos modos.

Si ustedes se encuentran la construcción de sistemas en los que es necesario especificar el tamaño de los enteros que está utilizando y por lo que tienden a usar Int16, Int32, UInt16, UInt32etc, entonces puede ser que parezca más natural de utilizar String- y cuando tenga que desplazarse entre diferentes lenguajes .NET que podría hacer las cosas más comprensibles; de lo contrario, usaría string e int.

0
230

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

Las palabras clave condicionales y de control (como if, switchy return) están en minúsculas y de color azul oscuro (por defecto). Y prefiero no tener el desacuerdo en el uso y formato.

Considerar:

String someString; 
string anotherString; 
0
208

stringy Stringson idénticos en todos los aspectos (excepto la "S" mayúscula). No hay implicaciones de rendimiento de ninguna manera.

stringSe prefiere la minúscula en la mayoría de los proyectos debido al resaltado de sintaxis

0
201

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

string es un tipo en C #.

System.String es un tipo en CLR.

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

Teóricamente, podría implementar un compilador de C # que generara el código de bytes de Java. Una implementación sensata de este compilador probablemente se correlacionaría stringcon el java.lang.Stringfin de interoperar con la biblioteca de tiempo de ejecución de Java.

0
187

Este video de YouTube demuestra prácticamente en qué se diferencian.

Pero ahora para una larga respuesta textual.

Cuando hablamos de .NETdos cosas diferentes, una es el .NETmarco y la otra hay lenguajes ( C#, VB.NETetc.) que usan ese marco.

ingrese la descripción de la imagen aquí

" System.String" también conocido como "Cadena" ("S" mayúscula) es un .NETtipo de datos de marco, mientras que "cadena" es un C#tipo de datos.

ingrese la descripción de la imagen aquí

En resumen, "Cadena" es un alias (lo mismo llamado con diferentes nombres) 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, hay alias para otros tipos de datos de c # como se muestra a continuación: -

objeto:, System.Objectcadena:, System.Stringbool:, System.Booleanbyte:, System.Bytesbyte:, System.SBytecorto: System.Int16y así sucesivamente

Ahora la pregunta del millón de dólares 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 coherente. Pero desde la perspectiva de las mejores prácticas, cuando realiza una declaración de variable, es bueno usar "cadena" ("s" pequeña) y cuando la usa 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 declaró usando "cadena". En el lado derecho, estamos llamando a un método, por lo que "String" es más sensato.

string s = String.ToUpper() ;
1
  • ¿Pero ahora tienes 2 estilos en una línea? :)
    Wouter
    18 feb a las 16:25
177

La minúscula stringes un alias de System.String. Son iguales en C#.

Hay un debate sobre si se debe utilizar el tipo de sistema ( System.Int32, System.String, etc.) tipos o la C# aliases( int, string, etc.). Personalmente, creo que debería usar el C# aliases, pero esa es solo mi preferencia personal.

2
  • 7
    Ese es el problema, no son alias 'C #', son alias 'C'. No hay una 'cadena' o 'int' nativa en el lenguaje C #, solo azúcar sintáctico.
    Quarkly
    29 de mayo de 2015 a las 20:23
  • 19
    No estoy seguro de dónde vino "C", ya que la especificación del lenguaje C # 5 dice "La cadena de palabras clave es simplemente un alias para la clase predefinida System.String". en la página 85, párrafo 4.2.4. Todos los lenguajes de alto nivel son azúcar sintáctico sobre conjuntos de instrucciones de CPU y código de bytes. 24 de febrero de 2016 a las 6:57
165

stringes solo un alias de System.String. El compilador los tratará de forma idéntica.

La única diferencia práctica es el resaltado de sintaxis que mencionas, y que tienes que escribir using Systemsi lo usas String.

2
  • No necesita prefijar System para usar String. 18/10/08 a las 19:24
  • 20
    Tienes que incluir un using Systemal usar String, de lo contrario, obtendrás el siguiente error:The type or namespace name 'String' could not be found (are you missing a using directive or an assembly reference?)
    Ronald
    16/10/09 a las 17:53
151

Ambos son lo mismo. Pero desde la perspectiva de las pautas de codificación, es mejor usar en stringlugar de String. Esto es lo que generalmente usan los desarrolladores. por ejemplo, en lugar de usar Int32usamos intcomo intes alias paraInt32

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

127

Como dicen los demás, son iguales. StyleCop reglas, por defecto, harán cumplir su uso stringcomo un estilo de código C # las mejores prácticas, excepto cuando se hace referencia System.Stringfunciones estáticas, tales como String.Format, String.Join, String.Concat, etc ...

0
113

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

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

Proporcionaré dos ejemplos en los que las usingdirectivas no ayudarán .


Primero, cuando Stringes 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 se llama a un miembro no estático Formaty no se aplican métodos de extensión. En el caso anterior, aún puede ser posible utilizarlo Stringen otros contextos donde un tipo es la única posibilidad sintáctica. Por ejemplo, String local = "Hi mum!";podría estar bien (según el espacio de nombres y las usingdirectivas).

Peor: decir String.Concat(someSequence)probablemente (según usings) vaya al método de extensión Linq Enumerable.Concat. No pasará al método estático string.Concat.


En segundo lugar, cuando Stringes 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 del Examplemétodo se 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 él.

0
105

El uso de tipos de sistema facilita la migración entre C # y VB.Net, si le gustan ese tipo de cosas.

0
93

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

1
  • Buen punto. Si no se hubiera inventado la 'cuerda', no tendríamos ninguna confusión y no necesitaríamos esta discusión inútil. Todas nuestras aplicaciones funcionarían bien con String. 'int' parece útil si no le importa el tamaño de los bits, lo que ocurre la mayor parte del tiempo, y 'string' parece que solo se agrega para mantener la coherencia.
    Roland
    20 abr a las 12:20
86

stringes un alias (o abreviatura) de System.String. Eso significa que al escribir stringqueríamos decir System.String. Puede leer más en think link: 'cadena' es un alias / abreviatura de System.String.

0
83

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

The C# language specification states, “As a matter of style, use of the keyword is favored over use of the complete system type name.” I disagree with the language specification; I prefer to use the FCL type names and completely avoid the primitive type names. In fact, I wish that compilers didn’t even offer the primitive type names and forced developers to use the FCL type names instead. Here are my reasons:

  • I’ve seen a number of developers confused, not knowing whether to use string or String in their code. Because in C# string (a keyword) maps exactly to System.String (an FCL type), there is no difference and either can be used. Similarly, I’ve heard some developers say that int represents a 32-bit integer when the application is running on a 32-bit OS and that it represents a 64-bit integer when the application is running on a 64-bit OS. This statement is absolutely false: in C#, an int always maps to System.Int32, and therefore it represents a 32-bit integer regardless of the OS the code is running on. If programmers would use Int32 in their code, then this potential confusion is also eliminated.

  • In C#, long maps to System.Int64, but in a different programming language, long could map to an Int16 or Int32. In fact, C++/CLI does treat long as an Int32. Someone reading source code in one language could easily misinterpret the code’s intention if he or she were used to programming in a different programming language. In fact, most languages won’t even treat long as a keyword and won’t compile code that uses it.

  • The FCL has many methods that have type names as part of their method names. For example, the BinaryReader type offers methods such as ReadBoolean, ReadInt32, ReadSingle, and so on, and the System.Convert type offers methods such as ToBoolean, ToInt32, ToSingle, and so on. Although it’s legal to write the following code, the line with float feels very unnatural to me, and it’s not obvious that the line is correct:

    BinaryReader br = new BinaryReader(...);
    float val = br.ReadSingle(); // OK, but feels unnatural
    Single val = br.ReadSingle(); // OK and feels good
    
  • Many programmers that use C# exclusively tend to forget that other programming languages can be used against the CLR, and because of this, C#-isms creep into the class library code. For example, Microsoft’s FCL is almost exclusively written in C# and developers on the FCL team have now introduced methods into the library such as Array’s GetLongLength, which returns an Int64 value that is a long in C# but not in other languages (like C++/CLI). Another example is System.Linq.Enumerable’s LongCount method.

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

74

String ( System.String) es una clase en la biblioteca de clases base. string (minúsculas) es un trabajo reservado en C # que es un alias para System.String. Int32 vs int es una situación similar Boolean vs. bool. Estas palabras clave específicas del lenguaje C # le permiten declarar primitivas en un estilo similar a C.

71

Es una cuestión de convención, de verdad. stringsimplemente se parece más al estilo C / C ++. La convención general es utilizar los atajos que haya proporcionado el idioma elegido (int / Int para Int32). Esto se aplica a "objeto" y decimaltambién.

En teoría, esto podría ayudar a transferir 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 cambie cualquier intreferencia a de Int32todos modos solo para estar seguro.

69

Stringno es una palabra clave y se puede utilizar como identificador, mientras que stringes una palabra clave y no se puede utilizar como identificador. Y en el punto de vista funcional ambos son iguales.

68

Llegar tarde a la fiesta: uso los tipos CLR el 100% del tiempo (bueno, excepto si me veo obligado a 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 todos los lenguajes CLR tuvieran que poder admitir el conjunto de tipos CLR, por lo que el uso de los tipos CLR proporcionó 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 muestra VS para los tipos CLR.

La única decepción real es que la función de autocompletar usa el tipo C #, por lo que termino volviendo a escribir los tipos generados automáticamente para especificar el tipo CLR en su lugar.

Además, ahora, cuando veo "int" o "string", me parece realmente incorrecto, como si estuviera viendo el código C de los años 70.

0
57

@JaredPar (¡un desarrollador del compilador de C # y prolífico usuario de SO!) Escribió una excelente publicación de blog sobre este tema. Creo que vale la pena compartirlo aquí. Es una buena perspectiva sobre nuestro tema.

string vs. String is not a style debate

[...]

The keyword string has concrete meaning in C#. It is the type System.String which exists in the core runtime assembly. The runtime intrinsically understands this type and provides the capabilities developers expect for strings in .NET. Its presence is so critical to C# that if that type doesn’t exist the compiler will exit before attempting to even parse a line of code. Hence string has a precise, unambiguous meaning in C# code.

The identifier String though has no concrete meaning in C#. It is an identifier that goes through all the name lookup rules as Widget, Student, etc … It could bind to string or it could bind to a type in another assembly entirely whose purposes may be entirely different than string. Worse it could be defined in a way such that code like String s = "hello"; continued to compile.

class TricksterString { 
  void Example() {
    String s = "Hello World"; // Okay but probably not what you expect.
  }
}

class String {
  public static implicit operator String(string s) => null;
}

The actual meaning of String will always depend on name resolution. That means it depends on all the source files in the project and all the types defined in all the referenced assemblies. In short it requires quite a bit of context to know what it means.

True that in the vast majority of cases String and string will bind to the same type. But using String still means developers are leaving their program up to interpretation in places where there is only one correct answer. When String does bind to the wrong type it can leave developers debugging for hours, filing bugs on the compiler team, and generally wasting time that could’ve been saved by using string.

Another way to visualize the difference is with this sample:

string s1 = 42; // Errors 100% of the time  
String s2 = 42; // Might error, might not, depends on the code

Many will argue that while this is information technically accurate using String is still fine because it’s exceedingly rare that a codebase would define a type of this name. Or that when String is defined it’s a sign of a bad codebase.

[...]

You’ll see that String is defined for a number of completely valid purposes: reflection helpers, serialization libraries, lexers, protocols, etc … For any of these libraries String vs. string has real consequences depending on where the code is used.

So remember when you see the String vs. string debate this is about semantics, not style. Choosing string gives crisp meaning to your codebase. Choosing String isn’t wrong but it’s leaving the door open for surprises in the future.

Nota: Copio / pego la mayoría de las publicaciones del blog por razones de archivo. Ignoro algunas partes, por lo que recomiendo saltar y leer la publicación del blog si puede.

1
  • Me alegra encontrar esta respuesta aquí. Hay una diferencia y es importante. 7 dic.20 a las 20:58
51

No hay diferencia.

La palabra clave C # se stringasigna al tipo .NET System.String: es un alias que se ajusta a las convenciones de nomenclatura del lenguaje.

Del mismo modo, se intasigna a System.Int32.

0
48

Hay una cita sobre este tema del libro de Daniel Solís .

All the predefined types are mapped directly to underlying .NET types. The C# type names (string) are simply aliases for the .NET types (String or System.String), so using the .NET names works fine syntactically, although this is discouraged. Within a C# program, you should use the C# names rather than the .NET names.

42

Sí, no hay diferencia entre ellos, al igual que el booly Boolean.

42

cadena es una palabra clave y no puede usar cadena como identificador.

La cadena no es una palabra clave y puede usarla como identificador:

Ejemplo

string String = "I am a string";

La palabra clave string es un alias porque, System.Stringaparte del problema de la palabra clave, las dos son exactamente equivalentes.

 typeof(string) == typeof(String) == typeof(System.String)
2
  • 2
    La única pequeña diferencia es que si usa la clase String, necesita importar el espacio de nombres del sistema en la parte superior de su archivo, mientras que no tiene que hacer esto cuando usa la palabra clave string.
    Uttam
    4 de marzo de 2018 a las 9:29
  • Hay casos de uso simples en los que la declaración de igualdad fallaría ... Como definir un tipo de llamada String en el espacio de nombres bla e importar ese espacio de nombres en el archivo en el que se ejecuta la declaración de igualdad. 4/06/19 a las 13:36