/ / C # .NET 4.5 як отримати список унікальних об'єктів на основі `GetHashCode` - c #, .net

C # .NET 4.5 як отримати список унікальних об'єктів на основі `GetHashCode` - c #, .net

Я маю 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 для двох об'єктів, новий буде все-таки вставлений.