Linq Union - IEqualityComparer和执行次数

时间:2011-06-16 13:41:48

标签: linq gethashcode iequalitycomparer

出于兴趣,IEqualityComparer的具体实现的GetHashCode如何工作?

我问的原因是我使用linq来联合两个集合,当只有左集合有一个项目时,GetHashCode被调用两次。除此之外,如果两个集合都有一行,则会调用四次。

这是粗略的打字,但你会明白这一点。 GetHashCode被调用两次,我猜这是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;
       }
   }

}

由于

1 个答案:

答案 0 :(得分:0)

我对你的观察感到好奇,我只能对每个列表中的每个项目进行GetHashCode的单一检查。但就使用比较器Union的实现而言,请将其视为

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

如果可以添加项目,Add的{​​{1}}方法将返回true或false。在内部实现中,它将调用项目的HashSet并获取值,然后查看该值是否已存在于集合中。如果是,则将每个与匹配的哈希码进行比较以获得相等性。如果没有相等匹配(或者哈希代码尚不存在),则成功添加该项,并且该方法返回true。否则,不添加该项,并且该方法返回false。