2010-11-06 12 views
7

Tengo un problema con GetHashCode e Igual que he anulado para una clase. Estoy usando el operador == para verificar si ambos son iguales y espero que esto llame tanto a GetHashCode como a Igual si su código hash es el mismo para poder validar que son iguales.C# GetHashCode/Igual que la anulación no se llama

Pero para mi sorpresa, ninguno es llamado y el resultado de la prueba de igualdad es falso (mientras que de hecho debería ser cierto).

código de anulación:

public class User : ActiveRecordBase<User> 

     [...] 

     public override int GetHashCode() 
     { 
      return Id; 
     } 

     public override bool Equals(object obj) 
     { 
      User user = (User)obj; 
      if (user == null) 
      { 
       return false; 
      } 

      return user.Id == Id; 
     } 
    } 

cheque Igualdad:

if (x == y) // x and y are both of the same User class 
    // I'd expect this test to call both GetHashCode and Equals 
+4

Si el '' == tenía, de hecho, llame a su método 'Equals', entonces sería causar un desbordamiento de pila, ya que utiliza el' '== operador en el objeto ... – Guffa

+0

No hay nada en el código usted muestra que indicaría la necesidad de llamar a GetHashCode(). Eso solo se llama si usa su objeto como la clave de una colección. – RenniePet

Respuesta

11

operador == es completamente independiente de cualquiera de .GetHashCode() o .Equals().

Puede que le interese el Microsoft Guidelines for Overloading Equals() and Operator ==.

La versión corta es: Use .Equals() para implementar Comparaciones de igualdad. Use el operador == para comparaciones de identidad, o si está creando un tipo inmutable (donde cada instancia igual se puede considerar efectivamente idéntica). Además, .Equals() es un método virtual y puede ser anulado por subclases, pero el operador == depende del tipo de tiempo de compilación de la expresión donde se usa.

Finalmente, para ser consistente, implemente .GetHashCode() cada vez que implemente .Equals(). Operador de sobrecarga != cada vez que sobrecargue el operador ==.

+0

Mis objetos son mutables. Esperaba que llamar al operador == de hecho llamaría al método Equals, que he visto trabajando antes, pero no entiendo por qué no funciona ahora y funcionó antes ... – tomzx

+0

@tomzx: The '= = 'el operador nunca llama al método' .Equals() 'a menos que lo sobrecargue para hacerlo. –

+1

@Daniel Su consejo re "==" es incorrecto. Microsoft dice consistentemente que si desea una comparación de IDENTIDAD, debe usar "ReferenceEquals". Por ejemplo, considere cadenas. Si usa un generador de cadenas para crear dos cadenas que tengan el mismo CONTENIDO pero diferentes DIRECCIONES, entonces "==" devolverá TRUE (comparación de igualdad), pero ReferenceEquals devolverá FALSE. "==" generalmente se considera como una comparación de IGUALDAD, y generalmente se implementa como haciendo lo que haga un EQUAL de una clase. – ToolmakerSteve

1

quizás agregando un método más en su clase User.

public virtual bool Equals(User other) 
    { 
     if (ReferenceEquals(null, other)) return false; 
     if (ReferenceEquals(this, other)) return true; 
     return other.Id == Id; 
    }