使用带有容差的IEqualityComparer GetHashCode

时间:2017-01-05 18:41:34

标签: c# linq hashtable date-range iequalitycomparer

我正在尝试实施一个对日期比较有宽容的IEqualityComparer。我也研究过this question。问题是我无法使用解决方法,因为我在LINQ IEqualityComparer中使用.GroupJoin()。我尝试了一些允许容忍的实现。我可以让Equals()工作,因为我有两个对象,但我无法弄清楚如何实现GetHashCode()

我最好的尝试看起来像这样:

public class ThingWithDateComparer : IEqualityComparer<IThingWithDate>
{
    private readonly int _daysToAdd;

    public ThingWithDateComparer(int daysToAdd)
    {
        _daysToAdd = daysToAdd;
    }

    public int GetHashCode(IThingWithDate obj)
    {
        unchecked
        {
            var hash = 17;
            hash = hash * 23 + obj.BirthDate.AddDays(_daysToAdd).GetHashCode();
            return hash;
        }
    }

    public bool Equals(IThingWithDate x, IThingWithDate y)
    {
        throw new NotImplementedException();
    }
}

public interface IThingWithDate
{
    DateTime BirthDate { get; set; }
}

.GroupJoin()HashTable之后构建GetHashCode(),它会应用添加到所有/所有对象的日期。这不起作用。

2 个答案:

答案 0 :(得分:3)

从概念上讲,问题是不可能的。您试图以一种方式比较对象,这种方式没有您尝试使用它执行的操作所必需的相等形式。例如,GroupJoin取决于如果A等于B,B等于C,则A等于C的假设,但在您的情况下,这不是真的。 A和B可能“足够接近”,因为你想要将它们分组,但A和C可能不是。

您根本不需要实施IEqualityComparer,因为您无法履行所需的合同。如果你想创建一个集合中的项目映射到另一个集合中与它“足够接近”的所有项目,那么你将需要自己编写该算法(这样做有效可能很难,但这样做效率低下并不应该“那么困难”,而不是使用GroupJoin,因为它无法执行该操作。

答案 1 :(得分:1)

我无法找到为您的指定标准生成逻辑哈希码的任何方法 哈希码用于确定两个日期是否应该粘在一起。如果它们应该组合在一起,那么它们必须返回相同的哈希码。

如果你的&#34;浮动&#34;是5天,这意味着1/1/2000必须生成与1/4/2000相同的哈希码,而1/4/2000必须生成与1/8/2000相同的哈希码(因为它们都在5天内彼此的)。这意味着1/1/2000具有与1/8/2000相同的代码(因为如果a = b且b = c,a = c)。

1/1/2000和1/8/2000在5天之外&#34;浮动&#34;。