2011-06-16 4 views
0

Comment le GetHashCode d'une implémentation concrète de IEqualityComparer fonctionne-t-il?Linq Union - IEqualityComparer et # d'exécutions

La raison pour laquelle je demande est que j'utilise linq pour l'union deux collections, et quand seulement la collection gauche a un élément GetHashCode est appelé deux fois. Suite à cela, il est appelé quatre fois si les deux collections ont une rangée.

Il s'agit d'une saisie grossière, mais vous aurez compris. GetHashCode est appelé deux fois, ce que je devine est deux fois pour l'un élément dans listOne?

par exemple.

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

} 

Merci

+0

Vous avez ce qui ressemble à une ligne inachevée là, juste au-dessus de votre déclaration de retour. Parenthèse non fermée, déclaration ternaire inachevée. –

Répondre

0

Je suis curieux de connaître votre observation, je ne peux observer un seul chèque de GetHashCode pour chacun des éléments dans chaque liste. Mais jusqu'à une mise en œuvre de Union en utilisant votre comparateur, pensez comme ça

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

La méthode Add du HashSet retournera true ou false si l'élément peut être ajouté. Dans l'implémentation interne, il appellera GetHashCode de l'élément et obtiendra la valeur, puis verra si cette valeur existe déjà dans la collection. Si c'est le cas, il compare chacun avec le code de hachage correspondant pour l'égalité. S'il n'y a pas de correspondance d'égalité (ou si le code de hachage n'existait pas déjà), l'élément est ajouté avec succès et la méthode renvoie true. Sinon, l'élément n'est pas ajouté et la méthode renvoie false.