3

对于具有属性 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 变得相同。

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

4

3 回答 3

4

这是不可能的。

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

于 2010-07-16T18:56:41.400 回答
1

有可能的。GetHashCode 的唯一规则是,如果 A == B,A.GetHashCode() 必须等于 B.GetHashCode()。相反,如果 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());
于 2010-07-16T19:12:59.503 回答
0

如果您使用哈希表中的项目,则最初将使用它们的 GetHashCode 方法来测试是否相等,如果发现它们的哈希值相等,则将调用它们的 Equals 方法以确定它们是否相等。

从文档中:

“但这足以让 Hashtable 确定它们是相同的对象吗?不幸的是,没有。如果 Hashtable 找到两个具有相同哈希的对象,它会调用它们的 Equals 方法来查看这两个对象实际上是否相等。同样,默认如果两个对象是同一个类的两个不同实例,Object.Equals 的实现将返回 false。因此我们还需要在我们的类中添加 Equals 方法的覆盖。

于 2010-07-16T19:04:34.947 回答