2012-03-02 75 views
17

¿Cuál es la diferencia entre == y Equals() con el ejemplo? Sé que == se utiliza para comparar operador y Equals() método se utiliza para comparar el contenido de string.So i tratóDiferencia entre == operador y el método Equals() en C#?

// first example 
string s1 = "a"; 
string s2 = "a"; 
Console.Write(a.Equals(s2)); // returns true, but if I assign "b" to s2, 
          // then result will be false 

// second example 
string s1 ="a"; 
string s2 ="a"; 
Console.Write(s1 == s2);  // returns true 

cómo es esto? Ambas son referencias de objetos diferentes. Supongamos que consideramos que estos son referencia. Pero traté de usar como esto

string s1 = new string("ab"); 
string s2 = new string("ab"); 

estoy consiguiendo error de compilación tiempo que no puede convertir la serie de charlas

Respuesta

21

Están pasando varias cosas. En primer lugar, en este ejemplo:

string s1 = "a"; 
string s2 = "a"; 
Console.WriteLine(s1 == s2); 

Usted afirma que:

ambos son diferentes referencia de objeto.

Eso no es cierto debido a cadena de internamiento.s1 y s2 son referencias al mismo objeto. Las garantías C# especificación que - de la sección 2.4.4.5 de la especificación C# 4:

Cuando dos o más cadenas literales que son equivalentes de acuerdo con el operador de igualdad cadena (§7.10.7) aparecen en el mismo programa, estos literales de cadena se refieren a la misma instancia de cadena.

Así que en este caso particular, a pesar de ello obtener "verdadera", incluso si imprimió object.ReferenceEquals(s1, s2), o si lo hizo usar una comparación verdadera identidad de referencia con ==:

object s1 = "a"; 
object s2 = "a"; 
Console.WriteLine(s1 == s2); // Still prints True due to string literal interning 

Sin embargo, incluso si estos eran referencias a objetos separados, == es sobrecargado para string. La sobrecarga es una decisión en tiempo de compilación - la implementación a usar depende de los tipos de tiempo de compilación de los operandos. Así, por ejemplo:

string a = new string('x', 1); 
string b = new string('x', 1); 
Console.WriteLine(a == b); // Uses string's implementation, prints True 

object c = a; 
object d = b; 
Console.WriteLine(c == d); // Reference identity comparison, prints False 

compararlo con object.Equals(object) que es un método virtual. Como sucede, String sobrecarga este método así como, pero lo que es más importante lo anula. Así que si cambiamos nuestro código a:

string a = new string('x', 1); 
string b = new string('x', 1); 
Console.WriteLine(a.Equals((object) b)); 

object c = a; 
object d = b; 
Console.WriteLine(c.Equals(d)); 

... entonces tanto las llamadas de método en el código compilado simplemente habrá que object.Equals(object), pero van a todavía tanto impresos verdadera causa de polimorfismo: la puesta en práctica de String se utilizará.

Esto es lo que una llamada a la sobrecarga método se vería así:

string a = new string('x', 1); 
string b = new string('x', 1); 
Console.WriteLine(a.Equals(b)); // Calls string.Equals(string) 
+0

Dos preguntas: ¿por qué el molde de 'd' a' object', ya que ya es un objeto? Además, en la parte 'a Igual b ', yo llamaría tanto a la anulación de objeto como a la sobrecarga de cadena, por lo que es más claro cuál es la diferencia. – doekman

+0

@doekman: 1) Sí, no necesito el yeso en ese caso. 2) No estoy seguro de lo que quieres decir. –

+0

Quiero decir esto: ver el último informe. No recibí tu explicación directamente sobre sobrecarga/anulación ... – doekman

7

Presupuesto de la documentación de Equals:

La implementación predeterminada de iguales soportes igualdad de referencia para tipos de referencia e igualdad bit a bit para los tipos de valores. La referencia igualdad significa que las referencias de objeto que se comparan se refieren al mismo objeto . La igualdad de bits significa que los objetos que se comparan tienen la misma representación binaria.

Y el == operator:

Para los tipos de valor predefinidos, el operador de igualdad (==) devuelve verdadero si los valores de sus operandos son iguales, falso en caso contrario. Para los tipos de referencia que no sean de cadena, == devuelve verdadero si sus dos operandos hacen referencia al mismo objeto con . Para el tipo de cadena, == compara los valores de las cadenas .

Ahora volviendo a su pregunta: ¿por qué s1 == s2 devuelve verdad? Las cadenas son bestias especiales en .NET. Representan tipos de referencia inmutables. Están internados en .NET. Esto significa que si tiene 2 constantes de cadena con el mismo valor, se referirán a la misma instancia de objeto en tiempo de ejecución.

Presupuesto de la documentation:

El tiempo de ejecución de lenguaje común conserva almacenamiento de cadenas mediante el mantenimiento de una mesa , llamado el grupo interno, que contiene una sola referencia a cada cadena literal única declarada o creado mediante programación en tu programa En consecuencia, una instancia de una cadena literal con un valor particular de solo existe una vez en el sistema.

+0

No es * únicamente * debido a la práctica. La internación es la razón por la cual funcionaría incluso si se declarara que era de tipo 'objeto'. Pero incluso las referencias a distintos objetos de cadena con el mismo contenido funcionarían siempre que los tipos de tiempo de compilación involucrados sean ambos de cadena, debido a la sobrecarga del operador. La documentación que ha citado es engañosa, ya que sugiere que hay un manejo especial * solo para cadenas * - no lo hay, es solo que la cadena es * un * tipo de referencia que sobrecarga el operador ==. –

+1

También tenga en cuenta que la internación es un detalle de idioma -.NET proporciona los mecanismos, pero sería muy posible tener un lenguaje Dumb # que fuera igual que C# en todos los sentidos, excepto sin el interinato constante de cadena. –

2

Usted está pensando parece Java-esque. En Java, el operador == no se puede personalizar, por lo que para los tipos de referencia, siempre significa igualdad de referencia, mientras que significa igualdad de valor para los tipos primitivos. Por otro lado, Equals es para verificar la igualdad de valores en los tipos de referencia.

Las cosas son diferentes en C#, sin embargo. Ambos Equals y == pueden tener implementaciones personalizadas. La diferencia es que Equals es un método virtual (instancia), mientras que operator== es un método estático. Aparte de eso, pueden comportarse exactamente de la misma manera.

De manera predeterminada, tanto Equals como == verifican la igualdad de referencia para los tipos de referencia y la igualdad de valores para los tipos de valores. Sin embargo, para string, ambos están personalizados para verificar la igualdad de valores.

Cuestiones relacionadas