Linq Union - IEqualityComparer and # of executions
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>
{
publi开发者_高级运维c bool Equals(SearchResult x, SearchResult y){....}
public int GetHashCode(SearchResult obj)
{
unchecked
{
int result = 0;
result = (result * 397) ^ (obj.Name != null ?
return result;
}
}
}
Thanks
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.
精彩评论