IEqualityComparer using a list of strings as a comparator

I am trying to set up an IEqualityComparer that uses a list of strings as a comparison property.

When using Except and Intersect in the two lines of code below, all records are treated as "new" and none are recognized as "old".

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

      

This is my IEqualityComparer class (Words is a list)

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();
    }
}

      

+3


source to share


2 answers


Yours is GetHashCode

wrong. Use one of the following methods:

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;
    }
}

      



To answer why a collection doesn't override GetHashCode

, but uses object.GetHashCode

one that returns a unique value: Why doesn't C # implement GetHashCode for collections?

+5


source


Assuming you store Words

in List

, then calling GetHashCode

on it won't give you a hash of the elements in it, instead it will return the hash value from Object.GetHashCode

.



You need to implement your own hash function that enumerates words and generates a hash value.

0


source







All Articles