LINQ与自定义IEqualityComparer不同

时间:2015-08-07 14:10:59

标签: c# linq iequalitycomparer

所以,我有class这样:

public History
{
    int ProcessedImageId;
    string UserId;
    DateTime TimeStamp;
    ...   
}

LINQ查询中,我会在一段时间内得到每个"History"

现在,我还在执行第二个查询以检索多个日期Processed的图像。

这个,工作正常。这是我得到的一个例子。

enter image description here

现在,我想要的是获得相同的查询but without repeating the ID of the image。因此,如果图像被多次处理,我将第一次被修改。

所以,这就是我想要的:

#query holds the second query

var result = query.AsEnumerable().Distinct(new HistoryComparer());

而且,我的HistoryComparer看起来像这样:

public bool Equals(History x, History y)
{
    return x.ProcessedImageId == y.ProcessedImageId && x.TimeStamp != y.TimeStamp;
}

public int GetHashCode(History obj)
{
    return obj.TimeStamp.GetHashCode() ^ obj.ProcessedImageId.GetHashCode();
}

如您所见,I don't care about the date。这就是为什么如果日期不同,我会返回true。但是,这不起作用。我仍然得到相同的结果。我该怎么办?

谢谢

1 个答案:

答案 0 :(得分:4)

为了使相等比较器正常工作,除了比较相等的项目之外,它必须为它认为相同的事物产生相同的哈希码。您的代码有两个实现问题,导致它无法获得预期的结果。

您的实现的第一个问题是,当日期相同时,您声明历史记录不同:

public bool Equals(History x, History y) {
    return x.ProcessedImageId == y.ProcessedImageId && x.TimeStamp != y.TimeStamp;
    //                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}

删除此部分将恢复相等比较逻辑。

但是,这还不够,因为您还必须处理哈希码。它必须在计算中停止使用时间戳:

public int GetHashCode(History obj) {
    return obj.ProcessedImageId.GetHashCode();
}

此时,相等比较归结为比较ID。