/ / C # .NET 4.5 comment obtenir une liste d'objets uniques basée sur `GetHashCode` - c #, .net

C # .NET 4.5 comment obtenir la liste des objets uniques en fonction de `GetHashCode` - c #, .net

j'ai un IEnumerable d'objets qui ont redéfini GetHashCode méthode. J'ai supposé que si j'ajoute ces objets à HashSet<T>, il ne contiendrait que les objets uniques. Mais ça ne "t:

var set = new HashSet<SomeObject>();
Count = 0
set.Add(first);
true
set.Add(second);
true
set.Count
2
first.GetHashCode()
-927637658
second.GetHashCode()
-927637658

Alors, comment pourrais-je réduire mon IEnumerable structure des objets à ceux qui sont uniques en fonction de leur GetHashCode() valeur.

Bien que je ne sache pas si cela aide de quelque manière que ce soit:

public class SomeObject
{
...
public string GetAggregateKey()
{
var json = ToJson();
json.Property("id").Remove();
return json.ToString(); // without the `id`, the json string of two separate objects with same content could be the same
}

override public int GetHashCode()
{
// two equal strings have same hash code
return GetAggregateKey().GetHashCode();
}
...
}

Réponses:

4 pour la réponse № 1

Il ne suffit pas d'avoir seulement un GetHashCode méthode.

le GetHashCode Cette méthode est utilisée pour déterminer rapidement s’il existe déjà des candidats potentiels dans le hachage (ou le dictionnaire):

  • Si aucun objet existant dans le hashset n'a le même code de hachage, le nouvel objet n'est pas un doublon
  • Si un ou plusieurs objets existants dans le hachage ont le même code de hachage, le nouvel est un potentiel dupliquer

Pour savoir s’il s’agit simplement d’un doublon potentiel ou d’un réel dupliquer, Equals est utilisé.

Si vous n’avez pas implémenté cela, alors le object.Equals méthode sera utilisée, qui consiste simplement à comparer des références. Deux objets distincts ne seront donc jamais égaux, même s'ils peuvent avoir les mêmes valeurs de propriété et le même code de hachage.

La solution: implémenter Equals avec les mêmes règles que le GetHashCode, ou fournir un IEqualityComparer<T> mise en œuvre à votre hashset.


1 pour la réponse № 2

Regardez le Source de référence pour HashSet: Cette ligne (le 960 et son entourage) correspond à ce que vous recherchez:

if (m_slots[i].hashCode == hashCode && m_comparer.Equals(m_slots[i].value, value))

Le hachage de l'objet n'est utilisé que pour décider dans quel compartiment va l'objet. Si Equals renvoie false pour les deux objets, le nouveau sera toujours inséré.