Duas “strings” diferentes são a mesma instância de object?

O código é bastante auto-explicativo. Eu esperava quando fiz a1 e b1 que eu estava criando duas instâncias de cadeia de caracteres diferentes que contêm o mesmo texto. Então eu acho que a1 == b1 seria verdade, mas object.ReferenceEquals(a1,b1) seria falso, mas não é. Por quê?

 //make two seemingly different string instances string a1 = "test"; string b1 = "test"; Console.WriteLine(object.ReferenceEquals(a1, b1)); // prints True. why? //explicitly "recreating" b2 string a2 = "test"; string b2 = "tes"; b2 += "t"; Console.WriteLine(object.ReferenceEquals(a2, b2)); // prints False //explicitly using new string constructor string a3 = new string("test".ToCharArray()); string b3 = new string("test".ToCharArray()); Console.WriteLine(object.ReferenceEquals(a3, b3)); // prints False 

Objetos string literais são reunidos em instâncias únicas pelo compilador. Isso é realmente requerido pela especificação :

Cada string literal não resulta necessariamente em uma nova instância de string. Quando dois ou mais literais de cadeia que são equivalentes de acordo com o operador de igualdade de seqüência de caracteres (Seção 7.9.7) aparecem no mesmo assembly, esses literais de seqüência de caracteres se referem à mesma instância de seqüência de caracteres.

O compilador é otimizado para que os literais string sejam iguais ao operador “==” do que não é necessário criar uma nova instância e ambos se referem à mesma instância … Então, é por isso que sua primeira parte da pergunta respondeu True.

Embora string seja um tipo de referência, os operadores de igualdade (== e! =) São definidos para comparar os valores de objects de string, não de referências. Isso torna o teste de igualdade de string mais intuitivo. Por exemplo:

 string a = "hello"; string b = "h"; // Append to contents of 'b' b += "ello"; Console.WriteLine(a == b); Console.WriteLine((object)a == (object)b); 

Isso exibe “True” e, em seguida, “False” porque o conteúdo das seqüências de caracteres é equivalente, mas aeb não se referem à mesma instância de seqüência de caracteres.

O operador + concatena strings:

 string a = "good " + "morning"; 

Isso cria um object de string que contém “bom dia”.

As strings são imutáveis ​​- o conteúdo de um object string não pode ser alterado depois que o object é criado , embora a syntax mostre que você pode fazer isso. Por exemplo, quando você escreve esse código, o compilador cria, na verdade, um novo object de string para manter a nova seqüência de caracteres, e esse novo object é atribuído a b. A string “h” é então elegível para garbage collection.

 string b = "h"; b += "ello"; 

para mais referência, verifique isso no msdn e isso

O compilador otimiza este caso e dá a ambos a mesma referência à string. A sequência em C # é imutável?

Otimização do compilador. Simples assim.