2009-04-30 29 views
15

en C# ¿Qué sucede exactamente en el fondo cuando se hace una comparación con el operador "==" en dos objetos? ¿simplemente compara las direcciones? o es algo así como Equals() o CompareTo()?C# ¿qué hace el operador == en detalle?

PD: ¿qué pasa con el operador "==" en java? ¿se comporta de la misma manera?

+0

Sólo una información rápida: si sobrecarga ==, también debe implementar =!. Lo mismo vale para <= and > =. – Tarik

Respuesta

24

Por lo que yo sé:

  • compara los tipos de valor por valor (igualdad)
  • se comparan los tipos de referencia por referencia (identidad)
  • , excepto si el operador == está sobrecargado, a continuación, llama a eso.

Equals se implementa en el objeto y se puede anular también. La implementación predeterminada en Object realiza una comparación de referencia para los tipos de referencia. Entonces, por defecto, Equals y == hacen lo mismo.

Creo que en Java no se puede sobrecargar el operador ==. Pero mi conocimiento de Java está bastante desactualizado.

Editar: Tenga en cuenta que el operador == es un método estático. Está vinculado en tiempo de compilación, en base a los tipos de sus variables o campos. Equals es un método virtual que se encuentra en tiempo de ejecución, en función de los tipos de tiempo de ejecución reales.

+3

Excelente respuesta; al menos una omisión, sin embargo: http://stackoverflow.com/questions/806020/snip/806068#806068 –

+0

no puede anular == operador en java, para los tipos de referencia en java == siempre hará una referencia (identidad) comparación. –

+1

No puede anular operadores en C# porque no son virtuales. Solo puedes sobrecargarlos. –

4

From MSDN:

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

3

No ... el operador == no siempre se comporta igual en java y en C#.

Por ejemplo, con cuerdas; Java == compara las referencias de los objetos de cadena ... (si usa tipos primitve, == en java compara los valores). Es por eso que

// returns FALSE in JAVA 
(new String("test") == "test") 

no volverá cierto en java ...

En C#, en contraste, el operador == se comporta diferente en las cadenas. Por ejemplo, volverá cierto en el caso siguiente:

// returns TRUE in C# 
(new String("test".ToCharArray()) == "test") 
+0

Esto se debe a que el operador == no se puede sobrescribir en Java, sino en C#, y eso es lo que es para las cadenas. ¿Esto hace que el comportamiento del operador sea diferente? –

+0

Creo que es un error común cuando estás acostumbrado a escribir software en C# y luego usar Java en otro proyecto ... es por eso que quería señalarlo – Homes2001

9

Como una extensión a Stefan's excellent answer - Otra excepción es si los operandos implican Nullable<T> - en cuyo caso "levantadas" operadores aplican (14.2.7 en ECMA 334v4):

Para los operadores de igualdad == =

una forma elevada de un operador existe si los tipos de los operandos son ambos tipos de valor no anulable y si el tipo de resultado! es bool. La forma levantada se construye al agregar una sola? modificador para cada tipo de operando. El operador elevado considera dos valores nulos iguales, y un valor nulo desigual a cualquier valor no nulo. Si ambos operandos son no nulos, el operador levantado desenvuelve los operandos y aplica el operador subyacente a produce el resultado bool.

Lo que significa que es: porque no es un operador de igualdad entre (por ejemplo):

int i = ..., j = ...; 
bool eq = i == j; 

Por lo tanto hay un operador implícito de la forma (aunque hecho de otra manera):

int? i = ..., j = ...; 
bool eq; 
if(i.HasValue) { 
    if(j.HasValue) { // both have values; compare 
     eq = i.GetValueOrDefault() == j.GetValueOrDefault(); 
    } else { // one null; always false 
     eq = false; 
    } 
} else { // true if both null, else false 
    eq = !j.HasValue; 
} 
0

El comportamiento del operador == depende de cómo se haya declarado la variable a la que lo está aplicando (no en la clase del objeto, agregaré un ejemplo).

Para tipos de valores, comparará sus valores.

Para los tipos de referencia a == b devuelve verdadero si a es el mismo objeto que b, a menos que el operador == esté sobrecargado. No reemplazado como otros dijeron, no puede anular operadores en C# porque no son virtuales.

object obj_a, obj_b; string str_a, str_b;

 str_a = "ABC"; 
     str_b = new string("ABC".ToCharArray()); 
     obj_a = str_a; 
     obj_b = str_b; 

     Console.WriteLine("str_a == str_b = {0}", str_a == str_b); // in string == operator is overloaded 
     Console.WriteLine("str_a.Equals(str_b) = {0}", str_a.Equals(str_b)); // string overrides Object.Euqals 
     Console.WriteLine("obj_a == obj_b = {0}", obj_a == obj_b); // in object == operator is not overloaded 
     Console.WriteLine("obj_a.Equals(obj_b) = {0}", obj_a.Equals(obj_b)); // Object.Equesl is virtual and overridden method from string will be executed. 
     Console.ReadKey(); 

La salida de ese programa es

 
str_a == str_b = True 
str_a.Equals(str_b) = True 
obj_a == obj_b = False 
obj_a.Equals(obj_b) = True