用于Java Map的.NET Dictionary/IDictionary与equals()契约的Equals()契约

Dav*_*les 7 .net java collections equality immutability

怀旧的Collections.unmodifiableMap(),我一直在实现IDictionary基于这个讨论的只读包装器,我的单元测试很快遇到了一个问题:

Assert.AreEqual (backingDictionary, readOnlyDictionary);
Run Code Online (Sandbox Code Playgroud)

即使键值对匹配,也会失败.我玩了一下,看起来至少(感谢Simonyi)

Assert.AreEquals (backingDictionary, new Dictionary<..> { /* same contents */ });
Run Code Online (Sandbox Code Playgroud)

确实过去了.

我刚刚看了一下通过DictionaryIDictionary文档,并让我吃惊我找不到了Java的任何等同Map合约的两个Maps相等entrySet()s必须相等.(文档说Dictionary- IDictionary - 覆盖Equals(),但不要说覆盖的内容.)

所以看起来C#中的键值相等是Dictionary具体类的属性,而不是IDictionary接口的属性.这是正确的吗?整个System.Collections框架通常是否正确?

如果是这样,我有兴趣阅读一些关于为什么MS选择这种方法的讨论 - 以及在C#中检查集合内容是否相同的首选方法.

最后,我不介意指向经过良好测试的ReadOnlyDictionary实现.:)


ETA:要明确,我不是在寻找关于如何测试我的实现的建议 - 这是相对微不足道的.我正在寻找有关这些测试应该强制执行的合同的指导.为什么呢.


ETA:伙计们,我知道 IDictionary是一个接口,我知道接口无法实现方法.在Java中也是如此.然而,Java Map接口记录了该方法的某些行为的期望equals().当然必须有.NET接口执行这样的操作,即使集合接口不在其中.

Dav*_*les 2

对于后来的读者,这是我被告知/能够弄清楚的:

  1. 与 Java 集合不同,.NET 集合的契约不包含 Equals()或的任何特定行为GetHashCode()
  2. LINQEnumerable.SequenceEqual() 扩展方法适用于有序集合,包括字典 - 表示为 IEnumerable<KeyValuePair>; KeyValuePair是一个结构体,它的 Equals方法使用反射 来比较内容。
  3. Enumerable提供了其他可用于拼凑内容相等性检查的扩展方法,例如Union()Intersect()

我的想法是,尽管 Java 方法很方便,但如果我们谈论可变集合以及典型的隐式equals()语义(两个equal对象是可互换的),它们可能不是最好的主意。.NET 没有为不可变集合提供很好的支持,但开源PowerCollections库可以。