2012-02-16 18 views
65

Nunca he hecho esto antes, así que esperaba que alguien me mostrara el correcto de implementar una excepción de Except() y GetHashCode() para mi clase.Forma correcta de reemplazar Igual() y GetHashCode()

Estoy tratando de modificar la clase para que pueda usar el método LINQ Except().

public class RecommendationDTO{public Guid RecommendationId { get; set; } 
public Guid ProfileId { get; set; } 
public Guid ReferenceId { get; set; } 
public int TypeId { get; set; } 
public IList<TagDTO> Tags { get; set; } 
public DateTime CreatedOn { get; set; } 
public DateTime? ModifiedOn { get; set; } 
public bool IsActive { get; set; } 
public object ReferencedObject { get; set; } 
public bool IsSystemRecommendation { get; set; } 
public int VisibilityScore { get; set; } 

public RecommendationDTO() 
{ 
} 

public RecommendationDTO(Guid recommendationid, 
          Guid profileid, 
          Guid referenceid, 
          int typeid, 
          IList<TagDTO> tags, 
          DateTime createdon, 
          DateTime modifiedon, 
          bool isactive, 
          object referencedobject) 
{ 
    RecommendationId = recommendationid; 
    ProfileId = profileid; 
    ReferenceId = referenceid; 
    TypeId = typeid; 
    Tags = tags; 
    CreatedOn = createdon; 
    ModifiedOn = modifiedon; 
    ReferencedObject = referencedobject; 
    IsActive = isactive; 
} 

public override bool Equals(System.Object obj) 
{ 
    // If parameter is null return false. 
    if (obj == null) 
    { 
     return false; 
    } 

    // If parameter cannot be cast to Point return false. 
    RecommendationDTO p = obj as RecommendationDTO; 
    if ((System.Object)p == null) 
    { 
     return false; 
    } 

    // Return true if the fields match: 
    return (ReferenceId == p.ReferenceId);// && (y == p.y); 
} 

public bool Equals(RecommendationDTO p) 
{ 
    // If parameter is null return false: 
    if ((object)p == null) 
    { 
     return false; 
    } 

    // Return true if the fields match: 
    return (ReferenceId == p.ReferenceId);// && (y == p.y); 
} 

//public override int GetHashCode() 
//{ 
// return ReferenceId;//^y; 
//}} 

he echado un vistazo a http://msdn.microsoft.com/en-us/library/ms173147.aspx pero yo estaba esperando que alguien me podría mostrar dentro de mi propio ejemplo.

Cualquier ayuda sería apreciada.

Gracias

+0

En la página que ha vinculado a: "No es una buena idea anular operador == en tipos no inmutables". Hay otras formas mejores de hacer que Except() funcione. –

+0

@Henk Holterman anulando operador de igualdad == no se recomienda; anulando Iguales no es recomendado. –

+0

@SouhaiebBesbes - se recomienda (muy fuertemente) mantener '==' y 'Igual()' en sincronía. –

Respuesta

67

Puede sobrescribir equals() y GetHashCode() en su clase como esta:

public override bool Equals(object obj) 
{ 
    var item = obj as RecommendationDTO; 

    if (item == null) 
    { 
     return false; 
    } 

    return this.RecommendationId.Equals(item.RecommendationId); 
} 

public override int GetHashCode() 
{ 
    return this.RecommendationId.GetHashCode(); 
} 
+0

¿No tengo que implementar IEquatable <> ?: public class RecommendationDTO: IEquatable ... Cuando lo hago me sale un error: DataTransferObjects.RecommendationDTO no implementa el miembro de la interfaz System.IEquatable .Equals (DataTransferObjects.RecommendationDTO) – Nugs

+0

Esta es una solución muy básica que no aborda las mejores prácticas, especialmente con la generación de código hash y anulando los operadores == y! = Relacionados. – LostNomad311

+0

como verificación no es suficiente en el caso general porque obj podría ser una instancia de una clase derivada de la actual – ovolko

10
public override bool Equals(System.Object obj) 
{ 
    // Check if the object is a RecommendationDTO. 
    // The initial null check is unnecessary as the cast will result in null 
    // if obj is null to start with. 
    var recommendationDTO = obj as RecommendationDTO; 

    if (recommendationDTO == null) 
    { 
     // If it is null then it is not equal to this instance. 
     return false; 
    } 

    // Instances are considered equal if the ReferenceId matches. 
    return this.ReferenceId == recommendationDTO.ReferenceId; 
} 

public override int GetHashCode() 
{ 
    // Returning the hashcode of the Guid used for the reference id will be 
    // sufficient and would only cause a problem if RecommendationDTO objects 
    // were stored in a non-generic hash set along side other guid instances 
    // which is very unlikely! 
    return this.ReferenceId.GetHashCode(); 
} 
7

tener cuidado al usar una clave principal que la prueba para la igualdad en anulando Equals() porque solo funciona DESPUÉS de que el objeto se haya conservado. Antes de eso, sus objetos aún no tienen claves primarias y los ID de los que están en la memoria son cero.

Utilizo base.Equals() si cualquiera de los ID de objeto es cero pero probablemente hay una forma más robusta.

Cuestiones relacionadas