2012-02-16 2 views
65

Я никогда не делал этого раньше, поэтому я надеялся, что кто-то может показать мне, что делать с переопределением Except() и GetHashCode() для моего класса.Правильный способ переопределить Equals() и GetHashCode()

Я пытаюсь изменить класс, чтобы использовать метод 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; 
//}} 

Я принял взглянуть на http://msdn.microsoft.com/en-us/library/ms173147.aspx, но я надеялся, что кто-то может показать мне в моем собственном примере.

Любая помощь будет оценена по достоинству.

Спасибо

+0

На странице, с которой вы ссылаетесь на: «Не рекомендуется переопределять оператор == в неизменяемых типах». Существуют другие и лучшие способы сделать работу Except(). –

+0

@ Хенк Холтерман, переопределяющий оператор равенства == не рекомендуется; переопределение Equals не рекомендуется. –

+0

@SouhaiebBesbes - это (очень сильно) рекомендуется синхронизировать '==' и 'Equals()'. –

ответ

67

Вы можете переопределить Equals() и GetHashCode() на своем классе, как это:

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

Мне не нужно реализовывать IEquatable <> ?: public class РекомендацияDTO: IEquatable <РекомендацияDTO> ... Когда я получаю сообщение об ошибке: DataTransferObjects.RecommendationDTO не реализует член интерфейса System.IEquatable .Equals (DataTransferObjects.RecommendationDTO) – Nugs

+0

Это очень простое решение, которое не учитывает лучшие практики, особенно с генерацией хэш-кода и переопределением связанных операторов == и! =. – LostNomad311

+0

, поскольку проверки недостаточно в общем случае, поскольку obj может быть экземпляром класса, производного от текущего – 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

Будьте осторожны при использовании первичного ключа в качестве теста для равенства в переопределение Equals(), потому что он работает только после того, как объект был сохранен. До этого у ваших объектов еще нет первичных ключей, а идентификаторы из них в памяти равны нулю.

Я использую base.Equals(), если любой из идентификаторов объекта равен нулю, но, вероятно, существует более надежный способ.

Смежные вопросы