如何使用两种不同的相等组合来覆盖Equals和GetHashCode

时间:2014-08-07 13:10:43

标签: c# hashcode equality

我正在创建一个包含多个属性的自定义类的集合。以下是课程。

public class OnlineProductHierarchy
{
    public DateTime InsertDate { get; set; }
    public string InsertUserId { get; set; }
    public DateTime AmendDate { get; set; }
    public string AmendUserId { get; set; }
    public string Product { get; set; }
    public string TextField { get; set; }
    public string Value { get; set; }
    public bool IsDefault { get; set; }
}

为了使我的班级的两个对象被视为相等,TextFieldValueProduct必须相同,或者TextFieldValue如果IsDefault为真,则属性必须相同

所以我有两种不同的方法来衡量相等性,如果两者都是真的,那么对象应该被认为是相等的。我这样做是因为我可以在创建集合时使用HashSet来删除重复项。

使用正常列表并通过LINQ比较proepties不是一个选项,因为我需要不错的性能。

到目前为止,我有这个代码检查我的第一个条件之间的相等性,但我不确定如何修改它以包括我的第二个质量条件

 public override bool Equals(object obj)
    {
        OnlineProductHierarchy o = obj as OnlineProductHierarchy;

        return o != null && o.Product.ToUpper()
      == this.Product.ToUpper() &&  o.Value.ToUpper() == this.Value.ToUpper()
      && o.TextField.ToUpper() == this.TextField.ToUpper();
    }

    public override int GetHashCode()
    {
        return this.Product.ToUpper().GetHashCode() ^ 
        this.TextField.ToUpper().GetHashCode()
      ^ this.Value.ToUpper().GetHashCode();
    }

此代码现在可以在添加到TextFieldValueProduct规则的hastset时正确识别重复项,但我如何添加到此包含我的第二个规则?

修改

在评论和答案的帮助下,似乎无法在单个Equals + GetHashCode方法中执行我想要的操作。

所以@Lee建议的替代解决方案是创建两个具有不同IEqualityComparer实现的HastSets,如果其中任何一个在执行Add i时失败,则可以识别重复记录。

1 个答案:

答案 0 :(得分:0)

这可能会起作用,但正如@Lasse建议的那样,你需要小心:

public override bool Equals(object obj)
{
    OnlineProductHierarchy o = obj as OnlineProductHierarchy;

    if(o == null) return false;

    return (String.Compare(o.Product, this.Product, true) &&
           String.Compare(o.Value, this.Value, true) &&
           String.Compare(o.TextField, this.TextField, true))
           ||
           (o.IsDefault == this.Isdefault &&
           String.Compare(o.Value, this.Value, true) &&
           String.Compare(o.TextField, this.TextField, true));
}

public override int GetHashCode()
{
    //Not possible using your logic
}