如何将HashSet <t>用作字典键?</t>

时间:2011-05-06 10:34:51

标签: c# .net collections

我希望使用HashSet<T>作为词典的关键:

Dictionary<HashSet<T>, TValue> myDictionary = new Dictionary<HashSet<T>, TValue>();

我想从字典中查找值,以便包含相同项HashSet<T>的两个不同实例将返回相同的值。

HashSet<T> Equals()GetHashCode()的实现似乎没有这样做(我认为它们只是默认值)。我可以覆盖Equals()以使用SetEquals()GetHashCode()怎么办?我觉得我在这里错过了一些东西......

3 个答案:

答案 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>>,并在该比较器中进行所需的实现。