【问题标题】:IDictionary<TKey, TValue> implementation and contract for replacing valuesIDictionary<TKey, TValue> 替换值的实现和契约
【发布时间】:2016-01-14 08:52:05
【问题描述】:

在使用this[key] = newValue 实现值替换时我应该遵循接口IDictionary&lt;TKey, TValue&gt; 的“合同”吗?一个例子:

IDictionary<MyKey, string> dict = CreateEmptyDict();
var k1 = new MyKey(123);
var k2 = new MyKey(123);  
dict.Add(k1, "foo");
dict[k2] = "bar";

k1 和 k2 是这样的 k1.Equals(k2) 并且它们具有相同的哈希码,但它们是引用类型,所以 ReferenceEquals(k1, k2) == false

BCL Dictionary&lt;TKey, TValue&gt; 将包含 (k1, "bar")。 我的问题是:对于IDictionary&lt;TKey, TValue&gt; 的任何实现,我真的应该遵循这个“合同”吗?或者如果在底层数据结构中更容易这样做,我可以让我的实现包含(k2, "bar")

【问题讨论】:

标签: c# .net


【解决方案1】:

至少在某种程度程度上是特定于实现的。例如,Dictionary&lt;,&gt; 允许您指定 IEqualityComparer&lt;T&gt; 用于检查键是否相等,而 SortedDictionary&lt;,&gt; 根本不使用 EqualsGetHashCode - 相反,它使用 IComparer&lt;T&gt; 来检查键排序

创建一个依赖于单独引用相等性的字典是完全合理的 - 但请确保您非常仔细地记录它。我会注意到,您实际上并不需要自己实现IDictionary&lt;,&gt; 来执行此操作...您只需要使用Dictionary&lt;,&gt; 和使用引用相等和RuntimeHelpers.GetHashCode() 的自定义相等比较器来获取@987654331 的哈希码@ 如果没有被覆盖,就会使用它。

实现字典会非常非常奇怪,这样您就可以多次添加确切的 same 值作为键 - 但是您如何判断键实际上是否相等是不同的没关系,IMO。

【讨论】:

  • 应该是IEqualityComparer&lt;T&gt; 而不是EqualityComparer&lt;T&gt;
  • @PetSerAl:已修复,谢谢。在会议的舞台上回答问题而分心:)
  • 谢谢,是的,我根本不使用哈希。我的 dict 的底层结构是一个树结构,在其中插入新的 kvp 比修改现有的 kvp 更容易(不像散列表,其中更新键的值很容易)。因此,在最直接的 impl 中,我将得到 (k2, v2) 而不是 BCL dict 的 (k1, v2)。
  • @AndersForsgren:一棵树表明您正在通过排序来比较键......此时,两个相等的键不会同样排序吗?
  • 底层树是四叉树,因此不存在真正的排序。示例 k1 = {"a", 1, 2}k2 = {"b", 1, 2} 以及仅查看网格坐标 1,2 的 dict 的相等比较器将替换该值,并且必须决定是否为该值保留键 k1k2。跨度>
猜你喜欢
  • 2013-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-25
  • 2011-01-22
  • 1970-01-01
  • 1970-01-01
  • 2014-02-19
相关资源
最近更新 更多