2010-11-20 14 views
15
String s1 = "Hello"; 
    String s2 = "Hello"; 

Aquí S1, S2 son diferentes, pero entonces ¿por qué ReferenceEquals() está regresando ciertoReferenceEquals ¿Por qué (S1, S2) devuelve verdadero

+1

¿Por qué escribe que son diferentes? – Lucero

+0

@ Lucero- int c = 5; int b = 5; Console.WriteLine (object.ReferenceEquals (b, c)); devuelve falso, difiere en caso de cadena solo – user498432

+1

en el caso de 'int', esa declaración implica * boxeo *, ya que' ReferenceEquals' acepta '(object, object)' - que es un ** muy ** escenario diferente ; 'string' es un tipo de referencia, por lo que no requiere boxeo. –

Respuesta

26

Esto se debe a internar - CLI automáticamente re-utiliza cadenas obtuvo como literales (es decir, cadenas que provienen directamente de su código fuente). Tenga en cuenta que si lo hizo:

char[] chars = {'h','e','l','l','o'}; 
string s1 = new string(chars); 
string s2 = new string(chars); 

que habría no ser la misma instancia de la cadena, ya que no han venido de literales.

Esto está documentado en contra de la Ldstr IL instruction:

El Common Language Infrastructure (CLI) garantiza que el resultado de dos instrucciones ldstr referencia a dos fichas de metadatos que tienen la misma secuencia de caracteres de retorno precisamente el mismo objeto de cadena (un proceso conocido como "cadena interna").

2

cadenas son inmutables, una vez que se crea en la memoria después mismos objetos String se refiere la objeto String creado previamente para más http://msdn.microsoft.com/en-us/library/362314fe.aspx

+1

Bueno, es un poco más restrictivo que eso; la pasantía (al menos, internamiento automático) solo se aplica a * literales *. –

1

si google "cadena ReferenceEquals"

que' obtendrá this

La siguiente fue la respuesta aceptada del enlace, en caso de que el enlace muera

En este ejemplo, "obj1" y "obj2" son instancias separadas, ¿verdad?

Las cadenas sin signo son tipos de referencia, y obj1 y obj2 son dos variables que apuntan a la misma instancia, debido en parte a algo llamado interning; básicamente, cualquier literal de cadena en un ensamblado * puede compartir la misma referencia de cadena. Esto es posible solo porque las cadenas son inmutables. También puede verificar cadenas internas (string.IsInterned), y pasante manual si lo desea (string.Intern).

Cuando dos cadenas tienen el mismo valor, ¿están compartiendo la misma instancia?

They might tienen la misma instancia; pero no está garantizado Las cadenas que se han generado sobre la marcha normalmente no serán internados; por ejemplo, los únicos que comparten referencias aquí son 2 & 4:

cadena tmp1 = "aa", tmp2 = "aaa";

cadena s1 = new string ('a', 5),

s2 = "aaaaa",

s3 = tmp1 + TMP2,

s4 = "aaaaa";

Consola.WriteLine (ReferenceEquals (s1, s2));

Console.WriteLine (ReferenceEquals (s1, s3));

Console.WriteLine (ReferenceEquals (s1, s4));

Console.WriteLine (ReferenceEquals (s2, s3));

Console.WriteLine (ReferenceEquals (s2, s4));

Console.WriteLine (ReferenceEquals (s3, s4));

* = estrictamente: Red-módulo

+1

Wow; eso me lleva unos años atrás :) –

+0

bueno, eso es interesante, una especie de "pequeño mundo" :) – shevski

2

cadena es immutable por lo utiliza misma referencia para el mismo valor Véase también Eric lippert blog para que todos sobre este

1

También puede utilizar String.Copy(String str) método estático para crear cadenas que lo hará ser objetos diferentes

String s1 = "Hello"; 
String s2 = string.Copy("Hello"); 

entonces s1 y s2 harán referencia a objetos diferentes.

Cuestiones relacionadas