IDictionary<TKey, TValue>实现和替换值的契约

4

在使用this[key] = newValue替换值时,我是否需要遵循实现IDictionary<TKey, TValue>接口的“合同”?以下是一个示例:

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<TKey, TValue>将包含(k1, "bar")。我的问题是:这是我应该遵循的任何IDictionary<TKey, TValue>实现的"契约"吗?或者如果在底层数据结构中这样做更容易,我可以让我的实现包含(k2, "bar")吗?

1
如果您不确定,您可以随时查看参考实现 - Domysee
1个回答

5
至少在某种程度上,它是实现特定的。例如,Dictionary<,>允许您指定一个IEqualityComparer<T>来检查键的相等性,并且SortedDictionary<,>根本不使用EqualsGetHashCode - 相反,它使用IComparer<T>来检查键的排序。
创建一个仅依赖于引用相等性的字典完全是合理的 - 但请确保您非常仔细地记录。我想注意的是,您不需要自己实现IDictionary<,>...只需要使用Dictionary<,>和自定义的相等比较器,该比较器使用引用相等性和RuntimeHelpers.GetHashCode()获取Object.GetHashCode()如果未被覆盖将使用的哈希码。
一个字典实现为您可以多次添加相同值作为键将是非常奇怪的 - 但如何判断键是否实际相等则是另一回事,我个人认为。

应该使用 IEqualityComparer<T> 而不是 EqualityComparer<T> 吗? - user4003407
2
@PetSerAl:已修复,谢谢。在会议的舞台上回答问题时有些分心 :) - Jon Skeet
谢谢,是的我根本不使用哈希。我的字典的底层结构是一棵树形结构,在这种结构中插入新的kvp比修改现有的kvp更容易(与哈希表不同,哈希表更新键的值很容易)。因此,在最直接的实现中,我将获得(k2,v2),而不是BCL字典的(k1,v2)。 - Anders Forsgren
@AndersForsgren:好的,基本上相当于自定义等式运算符,对吧? - Jon Skeet
@AndersForsgren:好的-如果可能的话,我会极力避免违反它。 - Jon Skeet
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接