【发布时间】:2010-05-21 11:49:22
【问题描述】:
假设我有一个类 T,我想将它用作 Dictionary<T,U> 集合中的键。
我必须在 T 中实现什么,以便这些键基于 T 的值而不是 T 引用?
我希望只是GetHashCode()。
【问题讨论】:
标签: c# generics dictionary gethashcode
假设我有一个类 T,我想将它用作 Dictionary<T,U> 集合中的键。
我必须在 T 中实现什么,以便这些键基于 T 的值而不是 T 引用?
我希望只是GetHashCode()。
【问题讨论】:
标签: c# generics dictionary gethashcode
您必须实现 GetHashCode() 和 Equals()。
字典是封面下的哈希表,因此您可能想阅读以下内容:Pitfalls Of Equals/GetHashCode – How Does A Hash Table Work?
【讨论】:
如果你没有在字典构造函数中传递任何IEqualityComparer<T>,它将使用MSDN定义的EqualityComparer<T>.Default:
Default 属性检查是否 类型 T 实现 System.IEquatable(Of T) 接口,如果是,则返回一个 EqualityComparer(Of T) 使用该实现。否则, 它返回一个使用覆盖的 EqualityComparer(Of T) T 提供的 Object.Equals 和 Object.GetHashCode。
所以实现IEquatable<T> 将是我的选择(如果你实现它,覆盖Equals 和GetHashCode 也是有意义的)。
【讨论】:
要么实现Equals和GetHashCode要么创建一个适当的IEqualityComparer<T>,它具有适合您的地图的相等匹配形式。
我更喜欢IEqualityComparer<T> 路线:在许多情况下,没有一种明显正确的平等形式 - 您希望根据情况以不同的方式将对象视为平等。在这种情况下,自定义相等比较器正是您所需要的。当然,如果存在 一个自然的相等操作,那么在类型本身中实现 IEquatable<T> 是有意义的......如果可以的话。 (IEqualityComparer<T> 的另一个好处是您可以为您无法控制的类型实现它。)
【讨论】:
您需要覆盖Equals(object obj)。当您修改Equals 时,总是希望您实现GetHashCode。在 MSDN 上阅读此 article。
【讨论】: