Я маю IEnumerable
об'єктів, які перевизначені GetHashCode
метод Я припустив, що якщо додати ці об'єкти HashSet<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
Так як я міг скоротити мій IEnumerable
структура об'єктів до тих, які унікальні на їх основі GetHashCode()
вартість
Хоча я не знаю, чи це допомагає будь-яким чином:
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();
}
...
}
Відповіді:
4 для відповіді № 1Недостатньо тільки мати GetHashCode
метод
The GetHashCode
Метод використовується для того, щоб швидко з'ясувати, чи є вже наявні потенційні кандидати в маскеті (або словнику):
- Якщо жоден існуючий об'єкт у машкеті не має однакового хеш-коду, новий не дублікат
- Якщо будь-який існуючий об'єкт (и) в машеті має той же хеш-код, новий - це потенціал дубльований
Щоб з'ясувати, чи це просто потенційний дубльований чи фактичний дубльований Equals
використовується.
Якщо ви не реалізовували це, то object.Equals
Буде використаний метод, який просто порівнює посилання. Таким чином, два різних об'єкта ніколи не будуть рівними, хоча вони можуть мати обидва значення однакового значення та однаковий хеш-код.
Рішення: реалізувати Equals
з тими ж правилами, що й GetHashCode
, або надати a IEqualityComparer<T>
реалізація вашої гашетки.
1 для відповіді № 2
Подивіться на Джерело довідника для HashSet: Ця лінія (960, а навколо) - це те, що ви шукаєте:
if (m_slots[i].hashCode == hashCode && m_comparer.Equals(m_slots[i].value, value))
Хеш об'єкта використовується лише для визначення того, яке відро об'єкт входить. Якщо Equals
повертає false для двох об'єктів, новий буде все-таки вставлений.