Qual é a diferença entre String e string em C #?


6510

Exemplo ( observe o caso ):

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

Quais são as diretrizes para o uso de cada um? E quais são as diferenças?


72
@ORMapper, mas permanece o fato de que stringé uma construção lexical da gramática C #, enquanto System.Stringé apenas um tipo. Independentemente de qualquer diferença explícita mencionada em qualquer especificação, ainda existe essa diferença implícita que pode ser acomodada com alguma ambiguidade. A própria linguagem deve suportar stringde uma maneira que a implementação não seja (completamente) obrigada a considerar para uma classe específica na BCL.
Kirk Woll

106
@ KirkWoll: De acordo com a especificação da linguagem, a própria linguagem deve considerar stringexatamente o mesmo que o tipo BCL System.String, nada mais. Isso não é ambíguo. Obviamente, você pode implementar seu próprio compilador, usando a gramática C #, e usar todos os tokens encontrados assim para algo arbitrário, não relacionado ao que é definido na especificação da linguagem C #. No entanto, o idioma resultante seria apenas semelhante a C #, não poderia ser considerado C #.
OR Mapper

88
Você pode usar stringsem uma diretiva de uso do sistema. Você não pode fazer isso com String.
Wilsu

14
Para alguém vindo de Algol e Fortran, essa discussão mostra que há algo errado string. É necessário abreviar System.String, mas, como um alias, parece bastante, mas não exatamente a mesma coisa. Após vários anos de C #, porém, eu diria, é seguro simplesmente usar stringe string.Format()e não se preocupar com System.String.
Roland

8
@Sangeeta O que você está dizendo? A System.Stringclasse ainda está lá e a stringpalavra-chave ainda é um alias para ela. Assim como System.Int32e int. Eles são literalmente a mesma coisa.
Craig

Respostas:


6105

stringé um alias em C # para System.String.
Então, tecnicamente, não há diferença. É como int vs. System.Int32 .

No que diz respeito às diretrizes, geralmente é recomendável usar stringsempre que você estiver se referindo a um objeto.

por exemplo

string place = "world";

Da mesma forma, acho que geralmente é recomendável usar Stringse você precisar se referir especificamente à turma.

por exemplo

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

Esse é o estilo que a Microsoft costuma usar em seus exemplos .

Parece que as orientações nesta área podem ter sido alteradas, já que o StyleCop agora impõe o uso de aliases específicos de C #.


163
Se você decidir usar o StyleCop e seguir isso, será necessário usar os tipos específicos para o idioma. Assim, para C # você terá string (em vez de String), int (em vez de Int32), float (em vez de Single) - stylecop.soyuz5.com/SA1121.html
Dominic Zukiewicz

144
Eu sempre uso os aliases porque presumi que um dia isso pode ser útil porque eles estão agindo como uma abstração, portanto, podem ter suas implementações alteradas sem que eu precise saber.
Rob

37
O Visual Studio 2015 diz que String.Format deve ser alterado para string.Format, então acho que a Microsoft está indo dessa maneira. Eu também sempre usei String para os métodos estáticos.
Sami Kuhmonen

32
Ao ler estas, reparei que vários dos comentários estão simplesmente incorretos. @ DRAirey1 Com o tempo, você descobrirá que a maneira antiga ainda é a melhor, se você duvida disso, eu te desafio a tentar escrever código C # sem usar o Visual Studio. É praticamente impossível e uma situação que surge de tempos em tempos no trabalho de desenvolvimento da web. @ Vlad Você não precisa importar nada para usar String. @Abhi Seu comentário é inútil e igualmente verdadeiro para string.Format(). @KlitosG Não, isso não é verdade. Todos eles funcionam exatamente da mesma maneira.
krowe2

46
Você poderia acrescentar que há, de fato, uma diferença? Por exemplo: nameof(string)não compilará, enquanto nameof(String)fará.
Jeroen Vannevel

3440

Apenas por uma questão de integridade, aqui está um despejo cerebral de informações relacionadas ...

Como outros observaram, stringé um apelido para System.String. Eles são compilados com o mesmo código, portanto, no tempo de execução, não há diferença alguma. Este é apenas um dos aliases em C #. A lista completa é:

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

Além de stringe object, os alias são todos para tipos de valor. decimalé um tipo de valor, mas não um tipo primitivo no CLR. O único tipo primitivo que não possui um alias é System.IntPtr.

Na especificação, os aliases de tipo de valor são conhecidos como "tipos simples". Os literais podem ser usados ​​para valores constantes de todos os tipos simples; nenhum outro tipo de valor tem formas literais disponíveis. (Compare isso com o VB, que permite DateTimeliterais e também possui um alias.)

Há uma circunstância em que você precisa usar os aliases: ao especificar explicitamente o tipo subjacente de uma enumeração. Por exemplo:

public enum Foo : UInt32 {} // Invalid
public enum Bar : uint   {} // Valid

Isso é apenas uma questão de como a especificação define enum declarações - a parte após os dois pontos tem que ser o tipo integrante de produção, que é um símbolo de sbyte, byte, short, ushort, int, uint, long, ulong, char... em oposição a um tipo de produção como usado por declarações variáveis, por exemplo. Não indica nenhuma outra diferença.

Finalmente, quando se trata de usar: pessoalmente, uso os aliases em todos os lugares para a implementação, mas o tipo CLR para qualquer API. Realmente não importa muito o que você usa em termos de implementação - a consistência entre sua equipe é boa, mas ninguém mais vai se importar. Por outro lado, é realmente importante que, se você se referir a um tipo em uma API, faça isso de maneira neutra em termos de idioma. Um método chamado ReadInt32é inequívoco, enquanto um método chamado ReadIntrequer interpretação. O chamador pode estar usando um idioma que define um intalias para Int16, por exemplo. Os designers .NET framework seguiram esse padrão, bons exemplos sendo nos BitConverter, BinaryReadere Convertclasses.


82
A situação de herança com enum é interessante. Você pode apontar para a documentação sobre por que o alias deve ser usado para enumerações? Ou isso é um bug conhecido?
JaredPar 19/10/08

149
Está na seção 14.1 das especificações (não posso citar aqui facilmente, pois é muito longo). Não diz explicitamente que você tem que usar o alias, mas os aliases são espécie de tratado como seus próprios tipos. É tudo um pouco estranho.
Jon Skeet

32
@PiPeep O que é mais surpreendente do que a grande quantidade de votos positivos é a baixa quantidade impressionante de votos negativos (considere que as 5 principais postagens têm um total de mais de 2000 votos positivos e, no entanto, apenas 1 voto negativo entre todos). Especialmente quando você considera a noção de que sempre há "inimigos" em qualquer comunidade, acho isso simplesmente incrível.
precisa saber é o seguinte

40
Uma diferença interessante entre stringe Stringé essa string' is a keyword in c#, so you can not use it as a variable name.For Ex: string string = "oi"; //compiler error, but String String = "hi"; `é aceitável, assim como Stringum identificador e não uma palavra-chave.
Sanjeev Rai 5/06

33
@SanjeevRai: Sim. Você pode usar @stringpara criar um identificador que acaba como stringse. É uma espécie de mecanismo de escape.
amigos estão dizendo sobre jon

716

Stringsignifica System.Stringe é do tipo .NET Framework. stringé um alias na linguagem C # para System.String. Ambos são compilados System.Stringem IL (Intermediate Language), portanto não há diferença. Escolha o que você gosta e use isso. Se você codificar em C #, eu prefiro string, pois é um alias do tipo C # e conhecido pelos programadores de C #.

Eu posso dizer o mesmo sobre ( int, System.Int32) etc.


3
`Se você codificar em C #, eu prefiro string, pois é um alias do tipo C # e bem conhecido pelos programadores de C #` - quando uma pessoa C # não conheceria o framework .NET. +1, pois geralmente acho que essa é a melhor resposta, mas o ponto que mencione parece estranho.
MyDaftQuestions

4
Pessoalmente, prefiro usar "Int32", pois mostra imediatamente o intervalo do valor. Imagine se eles atualizassem o tipo de "int" em sistemas posteriores de bits mais altos. Aparentemente, 'int' em c é visto como "o tipo inteiro com o qual o processador de destino é mais eficiente trabalhando" e definido como "pelo menos 16 bits". Eu preferiria consistência previsível lá, muito obrigado.
Nyerguds

2
@MyDaftQuestions concordo. Se alguma coisa faria sentido, use consistentemente os tipos .net porque eles são ignorantes e o tipo é óbvio, independente de qualquer idioma (conheço todas as idiossincrasias de F # ou VB?).
Peter - Restabelece Monica

5
@ Nyerguds Existem duas razões para simplesmente não se preocupar com isso. Uma é a intdefinida na especificação da linguagem C # como um inteiro de 32 bits, independentemente do hardware. O C #, apesar de uma herança compartilhada nas brumas do tempo, não é realmente C. Mudar intpara um número inteiro de 64 bits seria uma mudança de quebra na especificação e no idioma. Também seria necessário redefinir long, como longé atualmente o número inteiro de 64 bits. O outro motivo para não se preocupar é irrelevante, pois os tipos nunca mudam, mas o .NET é apenas abstrato o suficiente para que 99% das vezes você não precise pensar sobre isso de qualquer maneira. ;-)
Craig

5
@ Craig Eu cavo em lotes de formatos antigos de jogo proprietárias onde eu não tenho que pensar sobre isso o tempo todo, no entanto. E então usar Int16, Int32e Int64é muito mais transparente no código do que usar o bastante nãoshortintlong
descritivo

505

A melhor resposta que já ouvi sobre o uso dos aliases de tipo fornecidos em C # vem de Jeffrey Richter em seu livro CLR Via C # . Aqui estão suas três razões:

  • Eu já vi vários desenvolvedores confusos, sem saber se deveriam usar string ou String em seu código. Como no C # a cadeia de caracteres (uma palavra-chave) é mapeada exatamente para System.String (um tipo de FCL), não há diferença e pode ser usada.
  • Em C #, mapas longos para System.Int64 , mas em uma linguagem de programação diferente, longos podem ser mapeados para um Int16 ou Int32 . De fato, o C ++ / CLI realmente trata por muito tempo como um Int32 . Alguém que lê o código fonte em um idioma pode facilmente interpretar mal a intenção do código se ele ou ela estiver acostumado a programar em uma linguagem de programação diferente. Na verdade, a maioria das línguas não vai mesmo tratar longa como uma palavra-chave e não vai código de compilação que o utiliza.
  • O FCL tem muitos métodos que possuem nomes de tipo como parte de seus nomes de método. Por exemplo, o tipo BinaryReader oferece métodos como ReadBoolean , ReadInt32 , ReadSingle e assim por diante, e o tipo System.Convert oferece métodos como ToBoolean , ToInt32 , ToSingle e assim por diante. Embora seja legal escrever o código a seguir, a linha com float parece muito natural para mim e não é óbvio que a linha esteja correta:
BinaryReader br = new BinaryReader(...);
float val  = br.ReadSingle(); // OK, but feels unnatural
Single val = br.ReadSingle(); // OK and feels good

Então aí está. Eu acho que esses são realmente bons pontos. No entanto, não me vejo usando os conselhos de Jeffrey em meu próprio código. Talvez eu esteja muito preso no meu mundo C #, mas acabe tentando fazer meu código parecer com o código da estrutura.


24
O segundo ponto parece, na verdade, um motivo para não usar string, intetc.
MauganRa

15
@MauganRa E é suposto, o autor do livro lista essas razões pelas quais ele não usa apelidos.
tomi.lee.jones

31
"Se alguém está lendo o código-fonte C #, deve interpretar por muito tempo, de acordo com a especificação de idioma, e não com outra especificação de idioma." Isso erra totalmente o ponto. Não é que alguém pretenda interpretar mal o código, é simplesmente fácil para o cérebro chegar à conclusão errada quando um tipo tem um significado diferente daquele que o programador vê diariamente em outro contexto. Todos nós cometemos erros; o uso de tipos nomeados explicitamente torna esses erros menos prováveis.
Darryl

10
+ Esses motivos resumem meus sentimentos sobre o assunto. Quando comecei a codificar em C # (vindo de um plano de fundo Java / C ++ / C), pensei que os apelidos eram feios. Ainda me sinto assim, infelizmente a maior parte do mundo parece não concordar comigo, ou eles não se importam e, portanto, usam minúsculas.
precisa saber é o seguinte

8
@jinzai, a pergunta é sobre C #, na qual longé definido como um número inteiro de 64 bits assinado, independentemente da plataforma ou do compilador. Assim, em alguns casos, pelo menos, sim, não dependem do idioma.
phoog

455

stringé uma palavra reservada, mas Stringé apenas um nome de classe. Isso significa que stringnão pode ser usado como um nome de variável por si só.

Se, por algum motivo, você quiser uma variável chamada string , verá apenas a primeira dessas compilações:

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

Se você realmente deseja um nome de variável chamado string, pode usar @como prefixo:

StringBuilder @string = new StringBuilder();

Outra diferença crítica: o Stack Overflow os destaca de maneira diferente.


20
Lembre-se de que chamar um local @stringé realmente inútil, pois os nomes dos locais estão presentes apenas nos PDBs. Pode muito bem chamá-lo _stringou algo assim. Faz mais sentido coisas que têm nomes acessíveis por reflexão, onde @stringestaria o nome de um membro "string".
Roman Starkov 19/08/2013

25
Lembre-se também de usar uma palavra reservada, pois o nome da variável é deselegante.
Elton

7
O OP não deseja usar String ou string como um nome de variável. Eles pediram uma explicação da diferença entre esses tipos . Sua resposta só serve para adicionar mais confusão IMO
Matt Wilko

1
@ Craig se você estivesse escrevendo um software para ensinar as pessoas a amarrar nós?
Simon_Weaver

5
@Simon_Weaver knots em strings? haha, legal. :-) Claro, você pode escolher um nome alternativo, como thread. Espere um pouco ... D'oh!
Craig

391

Há uma diferença - você não pode usar Stringsem using System;antes.


14
por padrão, a maioria das pessoas adiciona isso de qualquer maneira na parte superior do arquivo. O VS faz isso por padrão na maioria dos casos, nem todos!
IbrarMumtaz 06/04

9
Por padrão, adiciono apenas as usinginstruções necessárias e removo explicitamente tudo o que não é necessário. Ferramentas de produtividade de energia> "[x] Remover e formatar usos ao salvar"
JMD

2
@JMD Modifiquei o arquivo de modelo .cs para que ele não tenha nenhuma instrução de uso na parte superior! Eu também mudei o modelo de classe para internal sealed.
ErikE 01/12/19

@JMD Eu odeio esse recurso. Às vezes, faz alterações em arquivos intocados, dificultando a visualização das alterações reais que um conjunto de alterações contém. É claro que normalmente removo "usando spam", mas apenas ativamente, não automaticamente.
mg30rg 19/02/19

Isso pode ser verdade para C #, mas não para todas as linguagens .NET. (Powershell importa o namespace System por padrão.)
FSCKur

311

Foi coberto acima; no entanto, você não pode usar stringna reflexão; você deve usar String.


6
Não entendo o que essa resposta significa e por que foi votada. Você pode usar typeof(string)na reflexão. Exemplo 1: if (someMethodInfo.ReturnType == typeof(string)) { ... }Exemplo 2: var p = typeof(string).GetProperty("FirstChar", BindingFlags.NonPublic | BindingFlags.Instance);Onde é que você deve usar String, não string? Se você tentar coisas como Type.GetType("String")ou Type.GetType("string"), nenhuma delas encontrará a classe porque o espaço para nome está ausente. Se, por algum motivo bobo, você comparar .Nameum tipo com "string"uma distinção entre maiúsculas e minúsculas, você está certo.
Jeppe Stig Nielsen

256

System.Stringé a classe de seqüência de caracteres .NET - em C # stringé um alias para System.String-, portanto, em uso elas são as mesmas.

Quanto às diretrizes, eu não ficaria muito atolado e usaria o que quisesse - há coisas mais importantes na vida e o código continuará o mesmo.

Se você encontrar-se a construção de sistemas onde é necessário especificar o tamanho dos inteiros que você está usando e assim tendem a usar Int16, Int32, UInt16, UInt32etc., então pode parecer mais natural para usar String- e quando se deslocam entre diferentes linguagens .NET que poderia tornar as coisas mais compreensíveis - caso contrário, eu usaria string e int.


2
Basta escolher um e ser consistente. Se você trabalha em algum lugar com um estilo de casa, use isso.
27615 Alan B #

3
infelizmente, o estilo é a preferência pessoal e pode ser muito caro para impor em uma grande base de código em várias equipes sem o proprietário do código dedicado. sempre há assuntos mais importantes para tratar do que string vs String. o que nos leva de volta a "coisas mais importantes da vida"
aiodintsov 24/02/16

Definitivamente, isso é uma coisa preferida; por exemplo: eu prefiro usar short, int, ushort, uintem vez de Int16, etc. Principalmente porque é assim que eu aprendi. Concedido, Int16é mais fácil entender imediatamente aqueles com menos experiência. +1 de mim!
Candleshark

210

Prefiro os .NETtipos de letra maiúscula (em vez dos aliases) por motivos de formatação. Os .NETtipos são coloridos da mesma forma que outros tipos de objetos (afinal, os tipos de valor são objetos adequados).

As palavras-chave condicionais e de controle (como if, switche return) são minúsculas e coloridas em azul escuro (por padrão). E eu preferiria não ter discordância quanto ao uso e formato.

Considerar:

String someString; 
string anotherString; 

11
Você também escreve código como: Int32 i = 1; Em vez de int i = 1; ? Parece inconsistente não usar o alias da string quando está disponível.
bytedev

29
@ashashwan: na verdade, sim, eu uso o Int32 i=1;intstead int i = 1; , acho que o primeiro é mais legível quanto à minha intenção: a saber, que eu quero um número inteiro assinado de 32 bits.
NotMe 15/02

5
Bem, acho que tudo depende se o desenvolvedor pensa que está escrevendo código C # (string) ou código .NET (String). Pessoalmente, acho que estou escrevendo C # (e é C # que está usando .NET).
precisa saber é o seguinte

7
@ Alex: meu argumento era simplesmente que eu prefiro ser muito específico na minha codificação, a fim de remover a ambiguidade.
NotMe

22
No extremo oposto do espectro, quase sempre uso var
tic

192

stringe Stringsão idênticos em todos os aspectos (exceto em maiúsculas "S"). Não há implicações de desempenho de qualquer maneira.

Letras minúsculas stringsão preferidas na maioria dos projetos devido ao realce da sintaxe


Jeffrey Richter recomenda usar o tipo CLR em todos os casos (CLR via C #) para evitar exatamente o tipo de confusão que está ocorrendo aqui.
18138 Josh

Claramente, se você usa S ou s, isso causou essas perguntas; portanto, vote menos Richter. ;)
Brad Wilson

Richter significava que a string não deveria ter sido uma opção - a Microsoft não deveria ter no idioma. Você não pode votar no Richter - ele é uma lenda! :)
Joe Ratzer 18/10/08

1
Concordo que poderia ter sido melhor não ter os pseudônimos. Mas dado que os temos, eu acho que não há problema em usá-los (mas não em nomes de métodos etc.)
Jon Skeet

10
"string" não é o mesmo que "String". Is significa "System.String". Portanto, se você usar "String", precisará colocar "using System" para incluir o espaço para nome
ThiagoAlves 3/11/11

185

C # é um idioma usado junto com o CLR.

string é um tipo em c #.

System.String é um tipo no CLR.

Quando você usa C # junto com o CLR string, é mapeado para System.String.

Teoricamente, você poderia implementar um compilador C # que gerasse o bytecode Java. A aplicação sensata deste compilador provavelmente mapear stringa java.lang.Stringfim de interoperar com a biblioteca de tempo de execução Java.


1
stringnão é um tipo em c #; é uma palavra reservada que mapeia para um tipo no CLR.
CesarGon

@CesarGon: De acordo com a ECMA-334, seção 8.2.1: "O C # fornece um conjunto de tipos predefinidos [...] Os tipos de referência predefinidos são objeto e string."
Rasmus Faber

10
De acordo com ECMA-334, seção 9.4.3, "string" é uma palavra-chave. :-) Eu concordo com você que "string" é um tipo se você se concentrar na semântica, mas eu diria que é uma palavra-chave (ou seja, uma palavra reservada) se você se concentrar na sintaxe. O padrão apoia os dois pontos de vista (talvez de maneira muito ambígua!). Para mim, o OP é sobre sintaxe, por isso tento me concentrar na sintaxe quando olho para as respostas, mas entendo o seu ponto também. Além disso, sua resposta, como está, pode ser interpretada como significando a existência de dois tipos diferentes: string e String, quando não for esse o caso. Um é um acasalamento para o outro.
CesarGon

Sejamos claros sobre isso. 'string' é um alias reservado. Não é um tipo de dados verdadeiro. É algo que aponta para outra coisa. Você pode remover todos esses aliases (ou nunca usá-los) e ter uma linguagem de programação perfeitamente boa.
Quarkly

168

Este vídeo do YouTube demonstra praticamente como eles diferem.

Mas agora, para uma longa resposta textual.

Quando falamos sobre, .NETexistem duas coisas diferentes, uma existe .NETframework e a outra há linguagens ( C#, VB.NETetc) que usam essa estrutura.

insira a descrição da imagem aqui

" System.String" aka "String" (capital "S") é um .NETtipo de dados da estrutura, enquanto "string" é um C#tipo de dados.

insira a descrição da imagem aqui

Em resumo, "String" é um alias (a mesma coisa chamada com nomes diferentes) de "string". Portanto, tecnicamente, as duas instruções de código abaixo fornecerão a mesma saída.

String s = "I am String";

ou

string s = "I am String";

Da mesma maneira, existem aliases para outro tipo de dados c #, como mostrado abaixo: -

objeto: System.Object, string: System.String, bool: System.Boolean, byte: System.Byte, sbyte: System.SByte, resumo: System.Int16e assim por diante

Agora, a pergunta de um milhão de dólares do ponto de vista do programador Então, quando usar "String" e "string"?

A primeira coisa a evitar confusão é usar um deles de forma consistente. Mas, da perspectiva das melhores práticas, quando você faz uma declaração variável, é bom usar "string" (pequeno "s") e, quando você o usa como nome de classe, é preferível "String" (capital "S").

No código abaixo, o lado esquerdo é uma declaração de variável e declarada usando "string". No lado direito, estamos chamando um método para que "String" seja mais sensato.

string s = String.ToUpper() ;

25
"Em resumo" String "é um alias (a mesma coisa chamada com nomes diferentes) de" string "". Isso não está correto: o alias é "string".
Xavier Egea #

3
quando você faz uma declaração variável, é bom usar "string" (pequeno "s") e quando você o usa como nome de classe, então "String" (maiúscula "S") é o preferido. Esta convenção parece não ser mais válida: se você usar o Visual Studio 2015 e tentar escrever Stringisso sugiro que você "simplificar o seu código", levando-o para string...
Massimiliano Kraus

165

Minúsculas stringé um alias para System.String. Eles são os mesmos C#.

Há um debate sobre se você deve usar os tipos de sistema ( System.Int32, System.String, etc.) Tipos ou o C# aliases( int, string, etc). Pessoalmente, acredito que você deve usar o C# aliases, mas essa é apenas a minha preferência pessoal.


4
Esse é o problema, eles não são aliases de 'C #', são aliases de 'C'. Não há 'string' ou 'int' nativo na linguagem C #, apenas açúcar sintático.
Quarkly

16
não tenho certeza de onde "C" veio daqui, pois a especificação da linguagem C # 5 diz "A cadeia de palavras-chave é simplesmente um alias para a classe predefinida System.String." na página 85, ponto 4.2.4. Todas as linguagens de alto nível são açúcar sintático sobre conjuntos de instruções da CPU e bytecode.
aiodintsov 24/02

156

stringé apenas um apelido para System.String. O compilador irá tratá-los de forma idêntica.

A única diferença prática é o destaque da sintaxe, como você menciona, e que você deve escrever using Systemse usar String.


Você não precisa prefixar System para usar String.
Joe Ratzer 18/10/08

18
Você precisa incluir um using Systemquando estiver usando String, caso contrário, você receberá o seguinte erro:The type or namespace name 'String' could not be found (are you missing a using directive or an assembly reference?)
Ronald

143

Ambos são iguais. Mas a partir de diretrizes de codificação perspectiva, é melhor usar stringem vez de String. Isso é o que geralmente os desenvolvedores usam. por exemplo, em vez de usar Int32usamos intcomo inté alias paraInt32

FYI "A palavra-chave string é simplesmente um alias para a classe predefinida System.String." - Especificação da linguagem C # 4.2.3 http://msdn2.microsoft.com/En-US/library/aa691153.aspx


120

Como os outros estão dizendo, eles são os mesmos. Regras StyleCop, por padrão, irá impor-lhe utilizar stringcomo um estilo de código C # melhor prática, exceto ao fazer referência a System.Stringfunções estáticas, tais como String.Format, String.Join, String.Concat, etc ...


4
Eu não sabia que o StyleCop sinalizaria o uso de String - exceto para métodos estáticos. Eu acho que é ótimo, pois é assim que eu sempre a uso: string para declarações de tipo e String quando eu acesso os membros estáticos.
Goyuix 5/05

101

Nova resposta após 6 anos e 5 meses (procrastinação).

Embora stringseja uma palavra-chave C # reservada que sempre tenha um significado fixo, Stringé apenas um identificador comum que pode se referir a qualquer coisa. Dependendo dos membros do tipo atual, o espaço para nome atual e as usingdiretivas aplicadas e seu posicionamento Stringpodem ser um valor ou um tipo diferente global::System.String.

Darei dois exemplos em que as usingdiretivas não ajudarão .


Primeiro, quando Stringé um valor do tipo atual (ou uma variável local):

class MySequence<TElement>
{
  public IEnumerable<TElement> String { get; set; }

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

O acima não será compilado porque IEnumerable<> não possui um membro não estático chamado Formate nenhum método de extensão se aplica. No caso acima, ainda pode ser possível usar Stringem outros contextos em que um tipo é a única possibilidade sintaticamente. Por exemplo, String local = "Hi mum!";pode ser bom (dependendo do espaço para nome eusing diretivas).

Pior: dizendo String.Concat(someSequence) é provável que o ditado (dependendo de using) vá para o método de extensão Linq Enumerable.Concat. Não irá para o método estático string.Concat.


Em segundo lugar, quando String é outro tipo , aninhado dentro do tipo atual:

class MyPiano
{
  protected class String
  {
  }

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

Nenhuma instrução no Examplemétodo é compilada. Aqui Stringé sempre um piano corda , MyPiano.String. Nenhum membro ( staticou não) Formatexiste nele (ou é herdado de sua classe base). E o valor"Goodbye" não pode ser convertido nele.


4
Suponho que sou diabólico: using String = System.Int32; using Int32 = System.String; e depois conte os insetos.
8265 Steve

7
Esta é a resposta certa. stringé System.String. Stringpoderia ser qualquer coisa.
Dave Cousineau

@DaveCousineau acordado - esse é o ponto do pseudônimo. Você pode criar outro Stringtipo que não seria definido como o objeto System.String. Confira: blog.paranoidcoding.com/2019/04/08
Kristopher

"A palavra string- chave tem significado concreto em C #. É o tipo System.Stringque existe no assembly principal do tempo de execução. O tempo de execução compreende intrinsecamente esse tipo e fornece os recursos que os desenvolvedores esperam stringsno .NET. Sua presença é tão crítica para o C # que, se esse tipo não existe, o compilador será fechado antes de tentar analisar uma linha de código. Portanto, stringtem um significado preciso e inequívoco no código C #. O identificador Stringainda não tem um significado concreto em C #. É um identificador que passa por todas as regras de pesquisa de nome as Widget, Studentetc… "
Kristopher



87

Contra o que parece ser prática comum entre os outros programadores, eu prefiro Stringmais string, apenas para destacar o fato de que Stringé um tipo de referência, como Jon Skeet mencionado.



78

Gostaria apenas de acrescentar isso à resposta da esquerda, do livro de Ritchers:

A especificação da linguagem C # declara: "Por uma questão de estilo, o uso da palavra-chave é favorecido sobre o uso do nome completo do tipo de sistema". Eu discordo da especificação de idioma; Prefiro usar os nomes de tipos FCL e evitar completamente os nomes de tipos primitivos. Na verdade, eu gostaria que os compiladores nem sequer oferecessem os nomes dos tipos primitivos e forçassem os desenvolvedores a usar os nomes dos tipos FCL. Aqui estão as minhas razões:

  • Eu já vi vários desenvolvedores confusos, sem saber se deveriam usar string ou String em seu código. Como na string C # (uma palavra-chave) mapeia exatamente para System.String (um tipo FCL), não há diferença e pode ser usada. Da mesma forma, ouvi alguns desenvolvedores dizerem que int representa um número inteiro de 32 bits quando o aplicativo está sendo executado em um sistema operacional de 32 bits e que representa um número inteiro de 64 bits quando o aplicativo está sendo executado em um sistema operacional de 64 bits. Essa declaração é absolutamente falsa: em C #, um int sempre mapeia para Int32 em seu código, então essa confusão em potencial também é eliminada. System.Int32 e, portanto, representa um número inteiro de 32 bits, independentemente do SO em que o código está sendo executado. Se os programadores usassem

  • Em C #, mapas longos para System.Int64 , mas em uma linguagem de programação diferente, longos podem ser mapeados para um Int16 ou Int32 . De fato, o C ++ / CLI trata por muito tempo como um Int32 . Alguém que lê o código fonte em um idioma pode facilmente interpretar mal a intenção do código se ele ou ela estiver acostumado a programar em uma linguagem de programação diferente. Na verdade, a maioria das línguas não vai mesmo tratar longa como uma palavra-chave e não vai código de compilação que o utiliza.

  • O FCL tem muitos métodos que possuem nomes de tipo como parte de seus nomes de método. Por exemplo, o tipo BinaryReader oferece métodos como ReadBoolean , ReadInt32 , ReadSingle e assim por diante, e o tipo System.Convert oferece métodos como ToBoolean , ToInt32 , ToSingle e assim por diante. Embora seja legal escrever o código a seguir, a linha com float parece muito natural para mim e não é óbvio que a linha esteja correta:

    BinaryReader br = new BinaryReader(...);
    float val = br.ReadSingle(); // OK, but feels unnatural
    Single val = br.ReadSingle(); // OK and feels good
  • Muitos programadores que usam C # exclusivamente tendem a esquecer que outras linguagens de programação podem ser usadas no CLR e, por causa disso, os organismos C # se infiltram no código da biblioteca de classes. Por exemplo, FCL da Microsoft é quase exclusivamente escrito em C # e desenvolvedores na equipe FCL já introduziu métodos para a biblioteca como matriz ‘s GetLongLength , que retorna um Int64 valor que é um longa em C #, mas não em outros idiomas (como C ++ / CLI). Outro exemplo é o método LongCount de System.Linq.Enumerable .

Não recebi a opinião dele antes de ler o parágrafo completo.


72

String ( System.String) é uma classe na biblioteca de classes base. string (minúscula) é um trabalho reservado em C # que é um alias para System.String. Int32 vs int é uma situação semelhante à atual Boolean vs. bool. Essas palavras-chave específicas do idioma C # permitem declarar primitivas em um estilo semelhante a C.


67

Stringnão é uma palavra-chave e pode ser usada como identificador, enquanto stringé uma palavra-chave e não pode ser usada como identificador. E no ponto de vista da função, ambos são iguais.


67

É uma questão de convenção, realmente. stringapenas se parece mais com o estilo C / C ++. A convenção geral é usar os atalhos fornecidos pelo idioma escolhido (int / Int for Int32). Isso vale para "objeto" e decimaltambém.

Teoricamente, isso poderia ajudar a transportar o código para algum padrão futuro de 64 bits no qual "int" possa significar Int64, mas esse não é o ponto, e eu esperaria que qualquer assistente de atualização alterasse as intreferências de Int32qualquer maneira apenas por segurança.


66

Chegando atrasado à festa: eu uso os tipos CLR 100% do tempo (bem, exceto se forçado a usar o tipo C #, mas não me lembro quando foi a última vez).

Eu originalmente comecei a fazer isso anos atrás, de acordo com os livros de Ritchie sobre CLR. Fazia sentido para mim que todas as linguagens CLR finalmente deveriam ser capazes de suportar o conjunto de tipos CLR, portanto, o uso dos tipos CLR forneceu um código mais claro e possivelmente mais "reutilizável".

Agora que faço isso há anos, é um hábito e gosto da cor que o VS mostra para os tipos de CLR.

A única desvantagem real é que o preenchimento automático usa o tipo C #, então acabo digitando novamente os tipos gerados automaticamente para especificar o tipo CLR.

Além disso, agora, quando vejo "int" ou "string", parece realmente errado para mim, como se estivesse vendo o código C dos anos 70.


49

Não há diferença.

A palavra-chave C # é stringmapeada para o tipo .NET System.String- é um alias que mantém as convenções de nomenclatura do idioma.

Da mesma forma, intmapeia para System.Int32.


Em uma compilação de 64 bits, int mapeia para System.Int64 (8 bytes), em 32 bits de construção que mapeia para System.Int32 (4 bytes)
Alex

1
IntPtr e UIntPtr são os únicos tipos que mudam de tamanho de acordo com a plataforma (desconsiderando tipos de ponteiros reais como int*e tipos compostos de [U] IntPtrs ou ponteiros reais).
P papai

45

Há uma citação sobre esse assunto no livro de Daniel Solis .

Todos os tipos predefinidos são mapeados diretamente para os tipos .NET subjacentes. Os nomes de tipo C # (string) são simplesmente aliases para os tipos .NET (String ou System.String), portanto, o uso dos nomes .NET funciona bem sintaticamente, embora isso não seja recomendável. Dentro de um programa C #, você deve usar os nomes C # em vez dos nomes .NET.


41

string é uma palavra-chave e você não pode usar string como um identificador.

String não é uma palavra-chave e você pode usá-lo como um identificador:

Exemplo

string String = "I am a string";

A palavra string - chave é um alias, System.Stringalém do problema da palavra-chave, os dois são exatamente equivalentes.

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

2
A única pequena diferença é que, se você usar a classe String, precisará importar o espaço para nome System no topo do arquivo, enquanto não precisará fazer isso ao usar a palavra-chave string.
Uttam

Existem casos de uso simples em que a instrução de igualdade falharia ... Como definir uma chamada de tipo String no namespace blah e importar esse namespace no arquivo no qual a instrução de igualdade está sendo executada.
rick

40

Sim, não há diferença entre eles, assim como o boole Boolean.


40

O @JaredPar (desenvolvedor do compilador C # e prolífico usuário de SO!) Escreveu um ótimo post sobre esse assunto. Eu acho que vale a pena compartilhar aqui. É uma boa perspectiva sobre o assunto.

stringvs. Stringnão é um debate de estilo

[...]

A palavra string- chave tem um significado concreto em C #. É o tipo System.Stringque existe no assembly de tempo de execução principal. O tempo de execução compreende intrinsecamente esse tipo e fornece os recursos que os desenvolvedores esperam para cadeias de caracteres no .NET. Sua presença é tão crítica para o C # que, se esse tipo não existir, o compilador será encerrado antes de tentar analisar uma linha de código. Portanto, stringtem um significado preciso e inequívoco no código C #.

O identificador, Stringporém, não tem significado concreto em C #. É um identificador que passa por todas as regras de pesquisa de nomes como Widget, Studentetc ... Poderia ligar-se a uma string ou a um tipo em outro assembly inteiramente cujas finalidades podem ser totalmente diferentes string. Pior ainda, poderia ser definido de uma maneira que o código goste String s = "hello"; continuou a compilar.

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;
}

O significado real de Stringsempre dependerá da resolução do nome. Isso significa que depende de todos os arquivos de origem no projeto e de todos os tipos definidos em todos os assemblies referenciados. Em suma, é necessário um pouco de contexto para saber o que isso significa.

É verdade que na grande maioria dos casos Stringe stringse ligará ao mesmo tipo. Mas usar Stringainda significa que os desenvolvedores estão deixando seu programa para interpretação em locais onde há apenas uma resposta correta. Quando Stringse liga ao tipo errado, pode deixar os desenvolvedores depurando por horas, arquivando bugs na equipe do compilador e geralmente perdendo tempo que poderia ter sido salvo usando string.

Outra maneira de visualizar a diferença é com este exemplo:

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

Muitos argumentam que, embora essas informações sejam tecnicamente precisas, o uso Stringainda é bom porque é extremamente raro que uma base de código defina um tipo desse nome. Ou que, quando Stringdefinido, é sinal de uma base de código incorreta.

[...]

Você verá que Stringé definido para um número de finalidades completamente válidos: ajudantes reflexão, bibliotecas de serialização, lexers, protocolos, etc ... Para qualquer uma destas bibliotecas Stringvs. stringtem consequências reais dependendo de onde o código é utilizado.

Então lembre-se de quando você vê o debate Stringvs. string, trata-se de semântica, não de estilo. A escolha da string fornece um significado nítido à sua base de código. Escolher Stringnão é errado, mas deixa a porta aberta para surpresas no futuro.

Nota: Copiei / colei a maior parte da postagem do blog por motivos de arquivamento. Eu ignoro algumas partes, por isso recomendo pular e ler a postagem do blog, se puder.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.