Ответ 1
Вы можете использовать установленный компаратор, предоставленный HashSet<T>
:
var myDictionary = new Dictionary<HashSet<T>, TValue>(HashSet<T>.CreateSetComparer());
Я хочу использовать HashSet<T>
как ключ к словарю:
Dictionary<HashSet<T>, TValue> myDictionary = new Dictionary<HashSet<T>, TValue>();
Я хочу искать значения из словаря, так что два разных экземпляра HashSet<T>
, которые содержат одни и те же элементы, возвращают одинаковое значение.
HashSet<T>
реализация Equals()
и GetHashCode()
, похоже, не делает этого (я думаю, что они просто значения по умолчанию). Я могу переопределить Equals()
для использования SetEquals()
, но как насчет GetHashCode()
? Я чувствую, что здесь что-то не хватает...
Вы можете использовать установленный компаратор, предоставленный HashSet<T>
:
var myDictionary = new Dictionary<HashSet<T>, TValue>(HashSet<T>.CreateSetComparer());
digEmAll ответ, безусловно, лучший выбор на практике, поскольку он использует встроенный код вместо того, чтобы изобретать колесо. Но я оставлю это как примерную реализацию.
Вы можете использовать реализацию IEqualityComparer<HashSet<T>>
, которая использует SetEquals
. Затем передайте его конструктору Словаря. Что-то вроде следующего (не проверял):
class HashSetEqualityComparer<T>: IEqualityComparer<HashSet<T>>
{
public int GetHashCode(HashSet<T> hashSet)
{
if(hashSet == null)
return 0;
int h = 0x14345843; //some arbitrary number
foreach(T elem in hashSet)
{
h = unchecked(h + hashSet.Comparer.GetHashCode(elem));
}
return h;
}
public bool Equals(HashSet<T> set1, HashSet<T> set2)
{
if(set1 == set2)
return true;
if(set1 == null || set2 == null)
return false;
return set1.SetEquals(set2);
}
}
Обратите внимание, что хеш-функция здесь коммутативна, что важно, потому что порядок перечисления элементов в наборе undefined.
Еще один интересный момент заключается в том, что вы не можете просто использовать elem.GetHashCode
, поскольку это даст неправильные результаты, когда пользовательский сопоставитель сравнений был поставлен в набор.
Вы можете предоставить IEqualityComparer<HashSet<T>>
конструктору словаря и внести желаемую реализацию в этот компаратор.