如何使用HashSet 作为字典键?

我希望使用HashSet作为Dictionary的键:

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

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

HashSetEquals()GetHashCode()实现似乎没有这样做(我认为它们只是默认值)。 我可以重写Equals()以使用SetEquals()但是GetHashCode()呢? 我觉得我在这里错过了一些东西……

您可以使用HashSet提供的set comparer:

 var myDictionary = new Dictionary, TValue>(HashSet.CreateSetComparer()); 

digEmAll的答案显然是实践中更好的选择,因为它使用内置代码而不是重新发明轮子。 但我会将此作为示例实现。


您可以使用实现使用SetEqualsIEqualityComparer> 。 然后将其传递给Dictionary的构造函数。 像下面的东西(没有测试):

 class HashSetEqualityComparer: IEqualityComparer> { public int GetHashCode(HashSet 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 set1, HashSet set2) { if(set1 == set2) return true; if(set1 == null || set2 == null) return false; return set1.SetEquals(set2); } } 

请注意,这里的哈希函数是可交换的,这很重要,因为集合中元素的枚举顺序是未定义的。

另一个有趣的一点是,您不能只使用elem.GetHashCode因为当向集合提供自定义相等比较器时,这会产生错误的结果。

您可以向Dictionary构造函数提供IEqualityComparer> ,并在该比较器中进行所需的实现。