【问题标题】:My IEquatable is still using Object.GetHashcode for Dictionary<T>[]我的 IEquatable 仍在为 Dictionary<T>[] 使用 Object.GetHashcode
【发布时间】:2014-02-14 15:20:21
【问题描述】:

我有类似以下内容作为通用字典的键。

class IMyClass<T> : IEquatable<IMyClass> where T : struct
{
  //etc
}


class MyClass<T> : IMyClass<T> where T : struct
{
    public bool Equals(IRatingKey<T> other)
    {
       //etc
    }
}

根据我对EqualityComparer&lt;T&gt;.Default 的了解,应该可以看出我已经实现了IEquatable&lt;T&gt;,因此动态创建了一个EqualityComparer。

Dictionary&lt;TKey, TValue&gt; 需要一个相等的实现来 判断键是否相等。如果比较器为空,则此 构造函数使用默认的泛型相等比较器, EqualityComparer&lt;T&gt;.Default。如果类型 TKey 实现 System.IEquatable&lt;T&gt; 泛型接口,默认相等比较器 使用该实现。

但是从我看到的使用字典索引器Dictionary&lt;T&gt;[] 来看,它仍然依赖于覆盖 GetHashcode,例如 public override int GetHashCode()

我可以看到有建议覆盖 很多 以保持一致性,但我正在尝试更多地理解它。是因为 IEquatable 应该直接位于 MyClass 而不是 IMyClass 中吗?但我更喜欢在 IMyClass 上使用它,因此实现者需要成为字典键。

我正在尝试使用 IEqualityComparer,但据我了解,我不需要它。

【问题讨论】:

  • 所以使用索引器肯定会使用GetHashCode(),这就是它生成原始哈希码的方式。用于确定添加时将其放置在哪个桶中的那个.
  • 嘿,有什么理由投票赞成或反对?我认为如果有人不确定字典是如何工作的,那么 SO 是一个很好的地方问...
  • True @MichaelPerrenoud,感谢您的反馈。我观察到它需要 GetHashCode() 并且需要它是有意义的。但是文档中并不清楚,所以我想确定一下。

标签: c# c#-4.0 dictionary generic-collections iequatable


【解决方案1】:

Dictionary 总是先检查GetHashCode,然后再去查看桶中的元素

假设 Dictionary 为长度为 L 的 Array,在添加新元素时,它会计算适当的索引,如

index = item.GetHashCode() % L

并将该元素放在适当桶的末尾(只是一个模型,实际上它也需要 Abs,并在必要时重新构建一个数组)

所以在任何时候它都有以下结构

---
 0  -> Item1, Item2
---
 1  -> Item3
---
 2 
---
...
---
L-1-> Item7

在查找时,字典再次计算索引,并使用 Equality 仅检查计算索引的桶元素。

【讨论】:

  • 感谢 Arsen,因此在文档中明确说明了 Dictionary 的其他部分如何在“外部”工作。但是在内部存储它仍然需要GetHashCode()?
  • 我说我不需要 IEqualityComparer 是否正确?正如 EqualityComparer.Default 为我整理出来的那样?
  • 是的,IEquatable 是关键,我相信 Dictionary.Default 将使用它即时创建一个 IEqualityComparer(有点?)
  • 是的 Alex,Dictinary 总是调用键的 GetHashCode 来确定桶,之后它使用 IEquatable 循环遍历桶元素。文档只是说第二部分,我相信你也可以在文档的某个地方找到第一个元素:)
  • 非常感谢,很高兴看到我不会生气。我希望有一个 IDictionaryKey,它会更容易:-)
猜你喜欢
  • 1970-01-01
  • 2020-06-30
  • 1970-01-01
  • 2023-01-31
  • 1970-01-01
  • 2011-09-11
  • 2016-04-24
  • 1970-01-01
  • 2011-03-18
相关资源
最近更新 更多