2011-06-16 47 views
0

出於興趣如何IEqualityComparer的具體實現的GetHashCode工作?Linq Union - IEqualityComparer和執行次數

我問的原因是我使用linq來聯合兩個集合,並且當只有左集合有一個項GetHashCode被調用兩次。除此之外,如果兩個集合都有一行,則會調用四次。

這是粗糙的打字,但你會明白的。 GetHashCode被調用兩次,我猜對於listOne中的一個項目是兩次?

例如

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

} 

感謝

+0

你有什麼看起來像一個未完成的行,就在你的return語句之上。未加密的括號,未完成的三元聲明。 – 2011-06-16 16:02:18

回答

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

HashSetAdd方法將返回true或false,如果可以加入該項目。在內部實現中,它將調用項目的GetHashCode並獲取該值,然後查看該值是否已在集合中存在。如果確實如此,則將它們與匹配的散列碼進行比較以求相等。如果不存在相等匹配(或者如果哈希碼尚不存在),則該項目被成功添加並且該方法返回true。否則,該項目不會被添加,並且該方法返回false。