IEqualityComparer使用字符串列表作为比较器

时间:2014-10-20 15:34:58

标签: c# iequalitycomparer

我正在尝试设置一个使用字符串列表作为比较属性的IEqualityComparer。

在下面两行代码中使用Except和Intersect时,所有记录都被视为“新”,并且没有一个被识别为“旧”。

List<ExclusionRecordLite> newRecords = currentRecords.Except(historicalRecords, new ExclusionRecordLiteComparer()).ToList();
List<ExclusionRecordLite> oldRecords = currentRecords.Intersect(historicalRecords, new ExclusionRecordLiteComparer()).ToList();

这是我的IEqualityComparer类(Words是一个列表)

public class RecordComparer : IEqualityComparer<Record>
{
    public bool Equals(Record x, Record y)
    {
        if (object.ReferenceEquals(x, y))
            return true;

        if (x == null || y == null)
            return false;

        return x.Words.SequenceEqual(y.Words);
    }

    public int GetHashCode(Record obj)
    {
        return new { obj.Words }.GetHashCode();
    }
}

2 个答案:

答案 0 :(得分:7)

您的GetHashCode不正确。使用这样的一个:

public override int GetHashCode()
{
    if(Words == null) return 0;
    unchecked
    {
        int hash = 19;
        foreach (var word in Words)
        {
            hash = hash * 31 + (word == null ? 0 : word.GetHashCode());
        }
        return hash;
    }
}

要回答为什么集合未覆盖GetHashCode但使用object.GetHashCode返回唯一值的原因:Why does C# not implement GetHashCode for Collections?

答案 1 :(得分:0)

假设您在Words中存储了List,那么在其上调用GetHashCode并不会给您回复其中的项目的哈希值,而是#&#t}} 39; ll会从Object.GetHashCode返回哈希值。

您需要实现自己的哈希函数,该函数枚举单词并生成哈希值。