.net

== frente a Object.Equals(objeto) en.NET



(8)

Entonces, cuando era un novato en comparación con el novato que soy ahora, solía pensar que estas dos cosas eran azúcar sintáctica entre sí, es decir, que usar una sobre la otra era simplemente una preferencia personal. Con el tiempo, he llegado a descubrir que estos dos no son lo mismo, incluso en una implementación predeterminada (ver esto y esto ). Para confundir aún más el asunto, cada uno puede ser anulado / sobrecargado por separado para tener significados completamente diferentes.

¿Es esto algo bueno, cuáles son las diferencias, y cuándo / por qué debería usar uno sobre el otro?


MSDN tiene descripciones claras y sólidas de ambas cosas.

método object.Equals

operador ==

Operadores sobrecargados

Pautas para anular Iguales () y operador ==

¿Es esto algo bueno, cuáles son las diferencias, y cuándo / por qué debería usar uno sobre el otro?

¿Cómo puede ser algo "bueno" o "malo"? Un método, otro operador. Si la igualdad de referencia no es suficiente, sobrecargúelos, de lo contrario déjelos como están. Para los tipos primitivos simplemente funcionan fuera de la caja.


Mi comprensión de los usos de ambos fue esta: use == para igualdad conceptual (en contexto, ¿estos dos argumentos significan lo mismo?) Y .Equals para igualdad concreta (¿son estos dos argumentos en realidad el mismo objeto exacto? )

Editar: El artículo vinculado de Kevin Sheffield hace un mejor trabajo al explicar el valor frente a la igualdad de referencia ...


Es posible que desee utilizar .Equals ya que alguien puede venir en otro momento y sobrecargarlos para su clase.


Dos de los tipos más utilizados, String e Int32 , implementan el operador == () y Equals () como igualdad de valor (en lugar de igualdad de referencia). Creo que uno puede considerar estos dos ejemplos definitorios , por lo que mi conclusión es que ambos tienen significados idénticos . Si Microsoft dice lo contrario , creo que están causando confusión intencionalmente.


string x = "hello"; string y = String.Copy(x); string z = "hello";

Para probar si x apunta al mismo objeto que y :

(object)x == (object)y // false x.ReferenceEquals(y) // false x.ReferenceEquals(z) // true (because x and z are both constants they // will point to the same location in memory)

Para probar si x tiene el mismo valor de cadena que y :

x == y // true x == z // true x.Equals(y) // true y == "hello" // true

Tenga en cuenta que esto es diferente a Java. En Java, el operador == no está sobrecargado, por lo que un error común en Java es:

y == "hello" // false (y is not the same object as "hello")

Para la comparación de cadenas en Java necesita usar siempre .equals()

y.equals("hello") // true


Operador == e Igual () son los mismos mientras comparamos valores en lugar de referencias. La salida de ambos son los mismos ver el ejemplo a continuación.

Ejemplo

static void Main() { string x = " hello"; string y = " hello"; string z = string.Copy(x); if (x == y) { Console.WriteLine("== Operator"); } if(x.Equals(y)) { Console.WriteLine("Equals() Function Call"); } if (x == z) { Console.WriteLine("== Operator while coping a string to another."); } if (x.Equals(y)) { Console.WriteLine("Equals() Function Call while coping a string to another."); } }

Salida:

== Operator Equals() Function Call == Operator while coping a string to another. Equals() Function Call while coping a string to another.


Iba a publicar esto como un comentario sobre la respuesta aceptada, pero creo que esto merece ser considerado al determinar qué ruta tomar.

dotnetfiddle: https://dotnetfiddle.net/gESLzO

Código de violín:

Object a = null; Object b = new Object(); // Ex 1 Console.WriteLine(a == b); // Ex 2 Console.WriteLine(b == a); // Ex 3 Console.WriteLine(b.Equals(a)); // Ex 4 Console.WriteLine(a.Equals(b));

Los primeros 3 ejemplos de WriteLine funcionarán, pero el cuarto arroja una excepción. 1 y 2 usan == , que es un método estático que no requiere la instancia de ningún objeto.

El ejemplo 3 funciona porque b se crea una instancia.

El ejemplo 4 falla porque a es null y, por lo tanto, no se puede invocar un método en un objeto nulo.

Como trato de codificar lo más perezosamente posible, uso == , especialmente cuando trabajo con escenarios donde cualquiera de los objetos (o ambos) puede ser nulo. Si no lo hiciera, primero tendría que hacer una comprobación nula antes de poder llamar a .Equals() .


Dada la declaración actual de Microsoft sobre operadores de igualdad == y != , La conclusión es: == debería ser azúcar sintáctica para Object.Equals() :

ASEGÚRESE de que Object.Equals y los operadores de igualdad tengan exactamente la misma semántica

desde http://msdn.microsoft.com/en-us/library/vstudio/7h9bszxx(v=vs.110).aspx

Que sean distintos , en lugar de solo azúcar, en retrospectiva, parece ser un error en su diseño.

Si quiere estar seguro de que está obteniendo una comparación de IDENTIDAD (cuando compara las referencias), use ReferenceEquals lugar.

Desafortunadamente, el manejo de == es tan inconsistente, que generalmente lo evito al manipular las clases personalizadas de otra persona, y simplemente uso los Equals(a, b) o los ReferenceEquals(a, b) menos legibles, según el significado que quiero.

En mi humilde opinión, sería mejor para las personas no implementar == y != En absoluto. Solo dejé .Net predeterminado en Equals y ! Equals ! Equals e implementa Equals según corresponda.

Si alguien tiene un razonamiento diferente, me gustaría escucharlo.

(Y sí, esto es realmente confuso, dado que Java existía primero, y usa == para significar ReferenceEquals . Pero es demasiado tarde para alterar .Net para comportarse de esa manera. Y tenemos la declaración de Microsoft para ese efecto, en el enlace dado anteriormente.)