0

Out of interest how does the GetHashCode of a concrete implementation of IEqualityComparer work?

The reason that I ask is that I'm using linq to union two collections, and when only the left collection has an item GetHashCode is called twice. Further to that, it's called four times if both collections have one row.

This is rough typing but you'll get the point. GetHashCode is called twice, which I'm guessing is twice for the one item in listOne?

e.g.

var listOne = new List<SearchResult>{new SearchResult{Name="Blah"}}; 
var listTwo = new List<SearchResult>(); 

listOne.Union(listTwo, SearchResultComparer); 

public class SearchResultComparer : IEqualityComparer<SearchResult>
{
   public bool Equals(SearchResult x, SearchResult y){....}

   public int GetHashCode(SearchResult obj)
   {
       unchecked
       {
           int result = 0;
           result = (result * 397) ^ (obj.Name != null ?                 
           return result;
       }
   }

}

Thanks

Mike Two
  • 44,935
  • 9
  • 80
  • 96
Tim Butterfield
  • 565
  • 5
  • 24

1 Answers1

0

I'm curious about your observation, I can only observe a single check of GetHashCode for each of the items in each list. But as far as an implementation of Union using your comparer, think of it like this

static IEnumerable<T> Union<T>(this IEnumerable<T> first, IEnumerable<T> second, IEqualityComparer<T> comparer)
{        
    // there's undoubtedly validation against null sequences

    var unionSet = new HashSet<T>(comparer);

    foreach (T item in first)
    {
        if (unionSet.Add(item))
            yield return item;
    }

    foreach (T item in second)
    {
        if (unionSet.Add(item))
            yield return item;
    }
}

The Add method of the HashSet will return true or false if the item can be added. In the inner implementation, it will make a call to the item's GetHashCode and get the value, and then see if this value already exists inside the collection. If it does, it compares each with the matching hash code for equality. If there is no equality match (or if the hash code did not already exist), the item is successfully added and the method returns true. Otherwise, the item is not added and the method returns false.

Anthony Pegram
  • 123,721
  • 27
  • 225
  • 246