Словари.NET имеют те же ключи и значения, но не “равны”

Этот тест сбои:

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
    }

Я неправильно понимаю что-то о как a Dictionary работы?

Я ищу Java, эквивалентный из .equals(), не попытка проверить справочное равенство.

17
задан John Saunders 8 February 2010 в 01:47
поделиться

4 ответа

Класс словаря не переопределяет метод Object.Equals , как видно из документа MSDN:

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

Определяет, равен ли указанный объект текущему объекту.

Видя, что вы выполняете модульное тестирование, ваш класс Assert должен предоставлять метод тестирования для проверки того, являются ли две коллекции одинаковыми.

Среда модульного тестирования Microsoft предоставляет класс CollectionAssert для сравнения коллекций:

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

EDIT Словарь реализует интерфейс 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 не доступен только для чтения, поэтому вы не скрываете все, используя это вместо конкретного Словаря ).

21
ответ дан 30 November 2019 в 11:12
поделиться

Проблема в этой строке кода:

Assert.AreEqual(dict, dictClone)

Вы сравниваете ссылки на объекты, которые не равны.

7
ответ дан 30 November 2019 в 11:12
поделиться

Я использовал метод расширения, который проверяет две последовательности на наличие одинаковых элементов

public static bool CheckForEquality<T>(this IEnumerable<T> source, IEnumerable<T> destination)
{
    if (source.Count() != destination.Count())
    {
        return false;
    }

    var dictionary = new Dictionary<T, int>();

    foreach (var value in source)
    {
        if (!dictionary.ContainsKey(value))
        {
            dictionary[value] = 1;
        }
        else
        {
            dictionary[value]++;
        }
    }

    foreach (var member in destination)
    {
        if (!dictionary.ContainsKey(member))
        {
            return false;
        }

        dictionary[member]--;
    }

    foreach (var kvp in dictionary)
    {
        if (kvp.Value != 0)
        {
            return false;
        }
    }

    return true;
}
4
ответ дан 30 November 2019 в 11:12
поделиться

Вы совершенно не понимаете, как работают ссылочные типы.

Словарь не переопределяет object.Equals () . Таким образом, он использует равенство ссылок - в основном, если обе ссылки указывают на один и тот же экземпляр, они равны, в противном случае - нет.

1
ответ дан 30 November 2019 в 11:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: