【问题标题】:Correct way to override Equals() and GetHashCode() [duplicate]覆盖 Equals() 和 GetHashCode() 的正确方法 [重复]
【发布时间】:2012-03-08 05:21:16
【问题描述】:

我以前从来没有真正这样做过,所以我希望有人能告诉我正确的方法是为我的班级实现 except() 和 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,但我希望有人可以在我自己的示例中向我展示。

任何帮助将不胜感激。

谢谢

【问题讨论】:

  • 在您链接到的页面上:“在非不可变类型中覆盖 operator == 不是一个好主意。”还有其他更好的方法可以让 except() 工作。
  • @Henk Holterman 不推荐覆盖相等运算符 ==;不建议覆盖 Equals。
  • @SouhaiebBesbes - (非常强烈)建议保持==Equals() 同步。

标签: c# equality gethashcode


【解决方案1】:

在覆盖 Equals() 时使用主键作为相等性测试时要小心,因为它仅在对象被持久化后才有效。在此之前,您的对象还没有主键,并且内存中的对象的 ID 都为零。

如果任何一个对象 ID 为零,我会使用 base.Equals(),但可能有更稳健的方法。

【讨论】:

    【解决方案2】:
    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();
    }
    

    【讨论】:

    • 如果对象没有 id 属性怎么办?
    【解决方案3】:

    您可以像这样在您的类上覆盖 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();
    }
    

    【讨论】:

    • 我不需要实现 IEquatable?: public class RecommendationDTO : IEquatable... 当我这样做时出现错误:DataTransferObjects.RecommendationDTO 没有实现接口成员 System.IEquatable.Equals(DataTransferObjects.RecommendationDTO)
    • 这是一个非常基本的解决方案,没有解决最佳实践,尤其是哈希码生成和覆盖相关的 == 和 != 运算符。
    • 在一般情况下检查是不够的,因为 obj 可能是从当前类派生的类的实例
    • System.ValueType派生的那些呢,例如structs而不是从System.Object派生的classes?
    • @code_dredd 结构见this answer
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多