【问题标题】:What must be done to use the value of a reference type as a dictionary key?必须做什么才能将引用类型的值用作字典键?
【发布时间】:2010-05-21 11:49:22
【问题描述】:

假设我有一个类 T,我想将它用作 Dictionary<T,U> 集合中的键。

我必须在 T 中实现什么,以便这些键基于 T 的值而不是 T 引用?

我希望只是GetHashCode()

【问题讨论】:

    标签: c# generics dictionary gethashcode


    【解决方案1】:

    您必须实现 GetHashCode() 和 Equals()。

    字典是封面下的哈希表,因此您可能想阅读以下内容:Pitfalls Of Equals/GetHashCode – How Does A Hash Table Work?

    【讨论】:

      【解决方案2】:

      如果你没有在字典构造函数中传递任何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> 将是我的选择(如果你实现它,覆盖EqualsGetHashCode 也是有意义的)。

      【讨论】:

      • 我不建议让任何可继承类型实现 IEquatable,因为如果派生类型覆盖 Object.Equals(Object) 和/或 Object.GetHashCode(Object) 以及IEquatable 的实现不会调用这些覆盖;由于强制转换为 Object 来调用这些覆盖会破坏使用通用接口获得的任何优势,因此实现它真的没有意义。
      【解决方案3】:

      要么实现EqualsGetHashCode要么创建一个适当的IEqualityComparer<T>,它具有适合您的地图的相等匹配形式。

      我更喜欢IEqualityComparer<T> 路线:在许多情况下,没有一种明显正确的平等形式 - 您希望根据情况以不同的方式将对象视为平等。在这种情况下,自定义相等比较器正是您所需要的。当然,如果存在 一个自然的相等操作,那么在类型本身中实现 ​​IEquatable<T> 是有意义的......如果可以的话。 (IEqualityComparer<T> 的另一个好处是您可以为您无法控制的类型实现它。)

      【讨论】:

        【解决方案4】:

        您需要覆盖Equals(object obj)。当您修改Equals 时,总是希望您实现GetHashCode。在 MSDN 上阅读此 article

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多