Equals,GetHashCode,EqualityComparers和模糊平等

时间:2010-07-16 18:52:51

标签: c# equals gethashcode

对于具有属性A,B,C,D,StartDate和EndDate的对象,如果我想实现任何两个对象相等的东西,如果它们具有相同的A,B和C以及重叠的日期范围,那将如何完成?

我尝试过像这样创建一个EqualityComparer

    public override bool Equals(RateItem x, RateItem y)
    {
        bool equal = true;
        if ((x.A != y.A || x.B != y.B || x.C != y.C ||
            (x.StartDate < y.StartDate && x.EndDate <= y.StartDate) ||
            (x.StartDate > y.StartDate && y.EndDate <= x.StartDate)))
        { equal = false; }
        return equal;
    }

但似乎框架中的很多地方都忽略了Equals并使用了GetHashCode,文档根本就不清楚。当我去实现GetHashCode时,我不知道如何在不忽略日期的情况下使HashCodes变为相同。

为了使其更加具体,这与项目管理和费率有关。我想实现一个业务规则,即同一个角色中同一个项目中的同一个人在同一时间段内不能有不同的费率。因此Bob在Project DeathMarch中担任DBA角色,在任何给定时间只能有一个有效的账单费率来记录他的时间。如果他需要在同一时间段内以不同的速率记录QA分析师的角色,那就没问题。这是一个庞大的预先存在的系统,因此不能选择更改域对象结构。

3 个答案:

答案 0 :(得分:4)

这是不可能的。

.Net中的平等必须是可传递的,这意味着如果a == bb == c,则a == c

答案 1 :(得分:1)

有可能。 GetHashCode的唯一规则是A.GetHashCode()必须等于B.GetHashCode()如果A == B.相反,如果A == B A.GetHashCode()== B.GetHashCode()则不一定真。

所以你可以像这样简单地制作GetHashCode

public override int GetHashCode()
{
    return A.GetHashCode() ^ B.GetHashCode() ^ C.GetHashCode();
}

GetHashCode不是为了身份!!它用于对“类似”对象进行分组。

证明:

string a = "a";
string b = "EUKCnPMLpp";
Console.WriteLine("a = '{0}', b = '{1}', Same = {2}", a, b, a == b);
Console.WriteLine("a.GetHashCode() = {0}, b.GetHashCode() = {1}, Same = {2}", a.GetHashCode(), b.GetHashCode(), a.GetHashCode() == b.GetHashCode());

答案 2 :(得分:0)

如果您正在使用散列表中的项目,那么他们的GetHashCode方法将使用最初来测试相等性,如果发现它们的散列相等,则将调用它们的Equals方法确定他们是否平等。

来自文档:

  
    

“但Hashtable足够了     确定它们是相同的     对象?很不幸的是,不行。如果     Hashtable使用。找到两个对象     相同的哈希,它称为等于     查看两个对象的方法     事实上是平等的。再次,默认     如果两个对象是Object.Equals的实现将返回false     两个不同的实例相同     类。所以我们还需要添加Equals的覆盖     我们班的方法。

  
相关问题