.NET字典具有相同的键和值,但不是“相等”如何解决?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (24)

此测试失败:

using Microsoft.VisualStudio.TestTools.UnitTesting;        

[TestMethod()]
        public void dictEqualTest() {
            IDictionary<string, int> dict = new Dictionary<string, int>();
            IDictionary<string, int> dictClone = new Dictionary<string, int>();

        for (int x = 0; x < 3; x++) {
            dict[x.ToString()] = x;
            dictClone[x.ToString()] = x;
        }

        Assert.AreEqual(dict, dictClone); // fails here
        Assert.IsTrue(dict.Equals(dictClone)); // and here, if the first is commented out
        Assert.AreSame(dict, dictClone); // also fails
    }

我是否误解了某Dictionary

我正在寻找Java的等价物.equals(),而不是试图检查参照平等。

提问于
用户回答回答于

Dictionary类不覆盖Object.Equals从MSDN doco中看到的方法:

http://msdn.microsoft.com/en-us/library/bsc2ak47.aspx

确定指定的Object是否等于当前的Object。

看到你在做单元测试,你的Microsoft单元测试框架提供了CollectionAssert用于比较集合的类:

http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.collectionassert_members%28VS.80%29.aspx

字典实现ICollection接口,你可以看到,如果只是工作?可能需要使用此重载来比较两个字典条目。

嗯IDictionary不实现ICollection,这是一个痛苦。然而,这工作(虽然是黑客):

IDictionary<string, int> dict = new Dictionary<string, int>();
IDictionary<string, int> dictClone = new Dictionary<string, int>();

for(int x = 0; x < 3; x++) {
    dict[x.ToString()] = x;
    dictClone[x.ToString()] = x;
}

CollectionAssert.AreEqual((System.Collections.ICollection)dict, (System.Collections.ICollection)dictClone);

上述方法适用于实例Dictionary,但是如果正在测试返回的方法,IDictionary则可能会因执行更改而失败。我的建议是改变代码来使用,Dictionary而不是IDictionary(因为IDictionary不是只读的,所以你没有用那个代替concreate来隐藏那么多Dictionary)。

用户回答回答于

如果你对如何从单元测试的角度来解决这个问题特别感兴趣:

尝试这个

CollectionAssert.AreEquivalent(dict.ToList(), dictClone.ToList());

说明

IDictionary上扩展方法 - 例如.ToList()- .Net 3.5及更高版本中的扩展方法,它们将字典转换为可与之轻松比较的KeyValuePair集合CollectionAssert.AreEquivalent

他们甚至会给出合理有用的错误消息!用法示例:

IDictionary<string, string> d1 = new Dictionary<string, string> {
    { "a", "1"}, {"b", "2"}, {"c", "3"}};

IDictionary<string, string> d2 = new Dictionary<string, string> {
    {"b", "2"}, { "a", "1"}, {"c", "3"}}; // same key-values, different order

IDictionary<string, string> d3 = new Dictionary<string, string> {
    { "a", "1"}, {"d", "2"}, {"c", "3"}}; // key of the second element differs from d1

IDictionary<string, string> d4 = new Dictionary<string, string> {
    { "a", "1"}, {"b", "4"}, {"c", "3"}}; // value of the second element differs from d1

CollectionAssert.AreEquivalent(d1.ToList(), d2.ToList());
//CollectionAssert.AreEquivalent(d1.ToList(), d3.ToList()); // fails!
//CollectionAssert.AreEquivalent(d1.ToList(), d4.ToList()); // fails!

// if uncommented, the 2 tests above fail with error:
//   CollectionAssert.AreEquivalent failed. The expected collection contains 1
//   occurrence(s) of <[b, 2]>. The actual collection contains 0 occurrence(s).     

扫码关注云+社区