繁体   English   中英

Equals,GetHashCode,EqualityComparers和模糊平等

[英]Equals, GetHashCode, EqualityComparers and fuzzy equality

对于具有属性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分析师的角色,那就没问题。 这是一个庞大的预先存在的系统,因此不能选择更改域对象结构。

这是不可能的。

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

有可能的。 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());

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

从文档:

“但这足以让Hashtable确定它们是相同的对象吗?不幸的是,没有。如果Hashtable发现两个具有相同散列的对象,它会调用它们的Equals方法来查看这两个对象是否实际上是相等的。再次,默认如果两个对象是同一个类的两个不同实例,则Object.Equals的实现将返回false。因此我们还需要向我们的类添加Equals方法的重写。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM