2012-03-22 11 views
15

Supongamos que definen dos tuplas:Tupla == Confusión

Tuple<float, float, float, float> tuple1 = new Tuple<float, float, float, float>(1.0f, 2.0f, 3.0f, 4.0f); 
Tuple<float, float, float, float> tuple2 = new Tuple<float, float, float, float>(1.0f, 2.0f, 3.0f, 4.0f); 

Si intento de comparar las tuplas, consigo resultados diferentes

bool result1 = (tuple1 == tuple2); // FALSE 
bool result2 = tuple1.Equals(tuple2); // TRUE 

que esperaría de ambas llamadas para volver realidad. ¿Qué es exactamente == comparando?

+0

http://msdn.microsoft.com/en-us/library/53k8ybth.aspx –

Respuesta

31

Para Tuple, == = está comparando las referencias del objeto porque no sobrecarga el operador ==. Dado que los objetos son equivalentes, pero no la misma instancia específica, Equals() rendimientos true y == rendimientos false.

Muchos tipos no sobrecargar ==, algunos prefieren mantener una distinción entre Equals() de equivalencia y == por la igualdad de referencia.

Además, basándose en == de equivalencia puede llevar a algunas rarezas:

public bool AreSame<T>(T first, T second) where T : class 
{ 
    return first == second; 
} 

El código anterior será siempre comprobar la igualdad de referencia debido a que un genérico sin restricciones se considera un object en tiempo de compilación, por lo tanto si el método no es virtual, obtendrá la versión del objeto (incluso si el tipo, como string, sobrecarga ==).

Por lo tanto este uso del código anterior:

var x = "Hello"; 
var y = "H"; 

// doing concat to avoid string interring 
AreSame(x, y+"ello"); 

Sí, las cadenas son equivalentes, sí T es string, pero el == está obligado a de == ya que el genérico no está restringido a objetos, por lo que este volverá false aunque el mismo código con los parámetros explícitos string devolvería true.

+0

Gracias Yo había asumido que '' == y 'Iguales' eran esencialmente lo mismo. Mi confusión proviene de directrices sobrecarga de MSDN, http://msdn.microsoft.com/en-us/library/ms173147%28v=vs.80%29.aspx, donde los '' == comprueba si hay algo más que hacen referencia a la igualdad. – lumberjack4

+0

La mejor regla empírica es comprobar la documentación de la clase para ver si implementan == operador, e incluso entonces, yo prefiero usar 'iguala a()' para mis cheques de equivalencia porque entonces es bastante obvio que eres buscando una verificación de equivalencia Pero ese soy yo. –

+0

AFAICT, AreSame ni siquiera compilará. Me sale el siguiente error del compilador: "operador '==' no se puede aplicar a operandos de tipo 'T' y 'T'" – RobSiklos

9

== está comparando referencias a objetos. La clase Tuple no sobrecarga el operador ==, por lo que debe usar .Equals.

+0

¿No es una buena práctica anular el operador ==? Asumí todo.Las clases NET anularon el operador ==. – lumberjack4

+0

Dado que 'Tuple' es inmutable, parece razonable argumentar que esta clase sería una buena candidata para sobrecargar al operador. Sin embargo, en mi experiencia, el único tipo de clase que alguna vez esperaba esta sobrecarga es en 'cadena' u otros tipos casi primitivos como' DateTime', 'TimeSpan', etc. –

9

== para Tupla sólo podrá ver las referencias y por lo tanto se verá que es falso.

PS: Recomendado manera es hacer algo como:

var tuple1 = Tuple.Create(1.0f, 2.0f, 3.0f, 4.0f) 
+0

Gracias a Dios n +1 por ese' .0f ', sin él, el compilador había estado gritando por el error' conversión doble flotante' ... – bonCodigo

+2

Y una vez que agregue el f, puede eliminar el '.0', es decir,' 1f', '2f', etc. – JotaBe