9

I come from a python world where only hashable objects may be used as keys to a dictionary. Is there a similar restriction in C#? Can you use custom types as dictionary keys?

4

3 回答 3

14

字典键的要求是它是可比较的和可散列的。这是 .NET 中的海龟,每种类型(指针类型除外)都派生自 System.Object,并且由于其 Equals() 方法,它始终具有可比性。并且由于它的 GetHashCode() 方法而可以散列。因此,任何 .NET 类型都可以自动用作键。

如果你想使用你自己的类型作为键,那么你只需要做一些特殊的事情,如果你想重新定义对象标识。换句话说,如果您需要两个不同对象相等的能力。然后,您将覆盖 Equals() 方法,通常比较对象的字段。然后你还必须重写 GetHashCode(),相等的对象必须生成相同的哈希码。

如果无法更改类型,或者您想为 Dictionary 自定义行为,则可以将自定义 IEqualityComparer<> 传递给构造函数。请记住,您使用自己的 GetHashCode() 生成的哈希码的质量决定了字典的效率。

于 2013-09-06T08:43:36.670 回答
2

是的,键的重要之处在于它们实现(或具有良好的默认实现)GetHashCodeEquals. 该Dictionary<T, K>实现可以利用 generic IEqualityComparer<T>

所有自定义类型都将附带 的默认实现,GetHashCode因为Equals它们是 的成员object,但是,该默认值可能并不总是与您的类型相关。

字典首先尝试获取哈希码以确定值将落入的存储桶。如果存在哈希冲突,它会退回到相等(我认为)。

请注意,您使用的密钥类型(class、、struct原始类型等)可能会产生不同的性能特征。在我们的代码库中,我们发现GetHashCodein的默认实现struct不如我们自己覆盖它快。我们还发现嵌套字典在访问时间方面比具有复合键的单个字典执行得更好。

于 2013-09-06T08:23:24.903 回答
2

是的,您可以,只需实现接口 IEqualityComparer,覆盖 GetHashCode 和 Equals。

于 2013-09-06T08:21:16.100 回答