gpt4 book ai didi

java - .NET Dictionary/IDictionary 的 Equals() 契约(Contract)与 Java Map 的 equals() 契约(Contract)

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:19:00 26 4
gpt4 key购买 nike

怀念Collections.unmodifiableMap(),我一直在实现基于this discussion 的只读IDictionary 包装器,我的单元测试很快就遇到了问题:

Assert.AreEqual (backingDictionary, readOnlyDictionary);

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

Assert.AreEquals (backingDictionary, new Dictionary<..> { /* same contents */ });

确实通过了。

我快速浏览了 DictionaryIDictionary文档,令我惊讶的是我找不到 Java Map 的任何等价物两个具有相同 entrySet()sMap 必须相等。 (文档说 Dictionary -- not IDictionary -- 覆盖 Equals(),但不要说该覆盖的作用。)

所以看起来 C# 中的键值相等是 Dictionary 具体类的属性,而不是 IDictionary 接口(interface)的属性。这是正确的吗?整个 System.Collections 框架是否普遍如此?

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

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


预计到达时间:明确地说,我不是寻找关于如何测试我的实现的建议——那是相对微不足道的。我正在寻找关于这些测试应该执行什么契约的指导。以及为什么。


ETA: 伙计们,我知道 IDictionary 是一个接口(interface),我知道接口(interface)不能实现方法。在 Java 中也是如此。然而,Java Map 接口(interface)记录了对 certain behavior 的期望。来自 equals() 方法。肯定有 .NET 接口(interface)可以做这样的事情,即使集合接口(interface)不在其中。

最佳答案

重写 equals 通常只对具有一定程度的值语义的类(例如 string)进行。引用相等性是人们更常关心的大多数引用类型和良好的默认值,特别是在可能不太清楚的情况下(两个字典具有完全相同的键值对但不同的相等比较器[因此添加相同的额外键值对可以使它们现在不同]相等或不相等?)或者不经常寻找值相等的地方。

毕竟,您要寻找的是两种不同类型被视为相等的情况。平等覆盖可能仍然会让你失败。

更重要的是,您总是可以足够快地创建自己的相等比较器:

public class SimpleDictEqualityComparer<TKey, TValue> : IEqualityComparer<IDictionary<TKey, TValue>>
{
// We can do a better job if we use a more precise type than IDictionary and use
// the comparer of the dictionary too.
public bool Equals(IDictionary<TKey, TValue> x, IDictionary<TKey, TValue> y)
{
if(ReferenceEquals(x, y))
return true;
if(ReferenceEquals(x, null) || ReferenceEquals(y, null))
return false;
if(x.Count != y.Count)
return false;
TValue testVal = default(TValue);
foreach(TKey key in x.Keys)
if(!y.TryGetValue(key, out testVal) || !Equals(testVal, x[key]))
return false;
return true;
}
public int GetHashCode(IDictionary<TKey, TValue> dict)
{
unchecked
{
int hash = 0x15051505;
foreach(TKey key in dict.Keys)
{
var value = dict[key];
var valueHash = value == null ? 0 : value.GetHashCode();
hash ^= ((key.GetHashCode() << 16 | key.GetHashCode() >> 16) ^ valueHash);
}
return hash;
}
}
}

这并不能满足人们想要比较字典的所有可能情况,但这就是我的观点。

用“大概是什么意思”的相等方法填充 BCL 会很麻烦,没有帮助。

关于java - .NET Dictionary/IDictionary 的 Equals() 契约(Contract)与 Java Map 的 equals() 契约(Contract),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3919358/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com