我希望使用HashSet<T>
作为词典的关键:
Dictionary<HashSet<T>, TValue> myDictionary = new Dictionary<HashSet<T>, TValue>();
我想从字典中查找值,以便包含相同项的HashSet<T>
的两个不同实例将返回相同的值。
HashSet<T>
Equals()
和GetHashCode()
的实现似乎没有这样做(我认为它们只是默认值)。我可以覆盖Equals()
以使用SetEquals()
但GetHashCode()
怎么办?我觉得我在这里错过了一些东西......
答案 0 :(得分:36)
您可以使用HashSet<T>
提供的设置比较器:
var myDictionary = new Dictionary<HashSet<T>, TValue>(HashSet<T>.CreateSetComparer());
答案 1 :(得分:7)
digEmAll的答案显然是实践中更好的选择,因为它使用内置代码而不是重新发明轮子。但我将把它作为一个示例实现。
您可以使用使用IEqualityComparer<HashSet<T>>
的{{1}}工具。然后将它传递给Dictionary的构造函数。如下所示(未测试):
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);
}
}
,因为当向集合提供自定义相等比较器时,这会产生错误的结果。
答案 2 :(得分:2)
您可以为Dictionary构造函数提供IEqualityComparer<HashSet<T>>
,并在该比较器中进行所需的实现。