0

興味深いことに、IEqualityComparerの具体的な実装のGetHashCodeはどのように機能しますか?

私が尋ねる理由は、linqを使用して2つのコレクションを結合し、左側のコレクションのみにアイテムがある場合、GetHashCodeが2回呼び出されるためです。さらに、両方のコレクションに1つの行がある場合、4回呼び出されます。

これは大まかなタイピングですが、要点はわかります。GetHashCodeは2回呼び出されますが、listOneの1つのアイテムに対して2回呼び出されると思いますか?

例えば

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

}

ありがとう

4

1 に答える 1

0

私はあなたの観察に興味がありますGetHashCode.各リストの各項目に対して1つのチェックしか観察できません. しかし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メソッドはtrue または false を返します。HashSet内部実装では、アイテムを呼び出してGetHashCode値を取得し、この値がコレクション内に既に存在するかどうかを確認します。一致する場合は、それぞれを一致するハッシュ コードと比較して等しいかどうかを調べます。同等の一致がない場合 (またはハッシュ コードがまだ存在しない場合)、アイテムは正常に追加され、メソッドは true を返します。それ以外の場合、項目は追加されず、メソッドは false を返します。

于 2011-06-16T14:08:22.537 に答える