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

C# 使用字符串列表作为比较器的IEqualityComparer,c#,iequalitycomparer,C#,Iequalitycomparer,我正在尝试设置一个IEqualityComparer,它使用字符串列表作为比较属性 在下面的两行代码中使用Except和Intersect时,所有记录都被视为“新”记录,没有一条记录被视为“旧”记录 List<ExclusionRecordLite> newRecords = currentRecords.Except(historicalRecords, new ExclusionRecordLiteComparer()).ToList(); List<ExclusionRe

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

在下面的两行代码中使用Except和Intersect时,所有记录都被视为“新”记录,没有一条记录被视为“旧”记录

List<ExclusionRecordLite> newRecords = currentRecords.Except(historicalRecords, new ExclusionRecordLiteComparer()).ToList();
List<ExclusionRecordLite> oldRecords = currentRecords.Intersect(historicalRecords, new ExclusionRecordLiteComparer()).ToList();
List newRecords=currentRecords.Except(historicalRecords,new ExclutionRecordLiteComparer()).ToList();
List oldRecords=currentRecords.Intersect(historicalRecords,new ExclutionRecordLiteComparer()).ToList();
这是我的IEqualityComparer类(单词是一个列表)

公共类记录器比较器:IEqualityComparer
{
公共布尔等于(记录x,记录y)
{
if(object.ReferenceEquals(x,y))
返回true;
如果(x==null | | y==null)
返回false;
返回x.Words.SequenceEqual(y.Words);
}
公共int GetHashCode(记录obj)
{
返回新的{obj.Words}.GetHashCode();
}
}

您的
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
,而是使用返回唯一值的值:

假设您正在
列表中存储
单词
,那么调用
GetHashCode
不会返回其中项目的哈希值,相反,它将从
Object.GetHashCode
返回哈希值


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

非常感谢,此设置可以正常工作。为什么哈希设置为19并乘以31?因为这是减少冲突可能性的素数。请注意,“false”冲突并不是那么糟糕,因为它将由
Equals
修复,但许多“false”冲突效率低下。
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;
    }
}