.NET字典具有相同的键和值,但不是"相等"

Nic*_*ner 17 .net c# dictionary equality

此测试失败:

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
    }
Run Code Online (Sandbox Code Playgroud)

我误解了一些有关Dictionary工作的方法吗?

我正在寻找Java的等价物.equals(),而不是试图检查引用相等性.

Igo*_*aka 21

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

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

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

看到您正在进行单元测试,您的Assert类应该提供一种测试方法来测试两个集合是否相同.

Microsoft Unit测试框架提供了CollectionAssert用于比较集合的类:

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

EDIT Dictionary实现了ICollection界面,你能看出它是否有效吗?您可能需要使用此重载来比较两个字典条目.

编辑 Hmm 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);
Run Code Online (Sandbox Code Playgroud)

上面的方法适用于实例Dictionary,但是如果你正在测试一个返回IDictionary它的方法,如果implmentation改变它可能会失败.我的建议是更改要使用的代码Dictionary而不是IDictionary(因为IDictionary不是readonly,所以你不是通过使用它而不是concreate来隐藏所有那么多Dictionary).


bac*_*car 10

如果您对如何从单元测试角度解决此问题特别感兴趣:

试试这个

CollectionAssert.AreEquivalent(dict.ToList(), dictClone.ToList());
Run Code Online (Sandbox Code Playgroud)

说明

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).     
Run Code Online (Sandbox Code Playgroud)


dcp*_*dcp 7

问题在于这行代码:

Assert.AreEqual(dict, dictClone)
Run Code Online (Sandbox Code Playgroud)

您正在比较不相等的对象引用.