Вопрос

У меня есть словарь, который я сравниваю с другим словарем (переменные, типизированные как IDictionary). Выполнение d1.Equals (d2) выдает false. Написание собственного кода ниже приводит к истине. Оба System.Collections.Generic.Dictionary. Я что-то упустил или у Dictionary нет реализации Equals, которая сравнивает ключи / значения?

private static bool DictEquals<K, V>(IDictionary<K, V> d1, IDictionary<K, V> d2)
{
    if (d1.Count != d2.Count)
        return false;

    foreach (KeyValuePair<K, V> pair in d1)
    {
        if (!d2.ContainsKey(pair.Key))
            return false;

        if (!Equals(d2[pair.Key], pair.Value))
            return false;
    }

    return true;
}
Это было полезно?

Решение

Dictionary.Equals () использует значение Equals from Object по умолчанию, проверяя, являются ли два объекта одинаковыми ссылками, как и все остальные коллекции по умолчанию. Вы можете создать свой собственный подкласс с семантикой значений, хотя обычно это включает в себя также неизменяемые вещи.

Другие советы

Вероятно, метод Equals класса Dictionary просто прибегает к реализации по умолчанию, унаследованной от Object, то есть он просто сравнивает ссылку на объект <=>, переданную с его собственной ссылкой. Смотрите здесь: Ссылка на Object.Equals

Если предположить, что два словаря, один из которых является SortedList<TKey, TValue>, а другой - Dictionary<TKey, TValue>, сравниваются на равенство, то должно ли действительно возвращаться значение true, если элементы совпадают? Это было бы довольно плохо, поскольку они имеют разные характеристики и особенности (например, SortedList<,> позволяет получать данные по индексу).

Кроме того, равенство и хеш-код логически связаны друг с другом. Хеш-код должен быть неизменным, иначе все алгоритмы, основанные на хэше, не будут работать. Вы не можете гарантировать это, когда используете содержимое для проверки на равенство. Следовательно, реализация по умолчанию (проверка того, являются ли они одним и тем же экземпляром) довольно разумна. Вы можете создать собственное сравнение равенства контента.

Другие упоминали, что он использует реализацию Object.Equals, вы можете использовать следующее для его переопределения:

public class EqualsDictionary<T, T> : Dictionary<T, T>
{
    public override bool Equals(object obj)
    {
        //Place your comparison implementation here
    }
}

Ссылки в .NET могут использоваться для инкапсуляции идентичности объекта, изменяемых аспектов его состояния, обоих или ни того, ни другого, в дополнение к инкапсуляции неизменяемых аспектов состояния объекта. В целом, при отсутствии конкретной причины для предположения обратного, .NET предполагает, что ссылки на изменяемые объекты используются для инкапсуляции идентификаторов. Кроме того, предполагается, что в тех случаях, когда код сравнивает ссылки, не зная, что они представляют, лучше ошибиться в сообщении о неравных вещах. Таким образом, две ссылки на изменяемые объекты обычно считаются эквивалентными, если и только если они идентифицируют один и тот же объект, и поэтому изменяемым типам не рекомендуется переопределять Equals для указания чего-либо еще. Вместо этого код, который использует ссылки для инкапсуляции изменяемого состояния, должен использовать другие средства, кроме Object.Equals(), для их сравнения.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top