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 № 1Il 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é.