Dictionary.ContainsKey неправильно ведет себя # - PullRequest
6 голосов
/ 22 июня 2011

У меня есть класс Column

public class Column
{
    public int Id { get; private set; }
    public string Name { get; private set; }
    public EPersonalCharacteristicType Type { get; private set; }
    public Column MainColumn { get; private set; }
}

, и у меня есть следующее поле в другом классе

Dictionary<Column, string> dictionary

В середине выполнения я получаю странныйПоведение этого dictionary.Когда я набрал

dictionary.ContainsKey(dictionary.Keys.ToList()[1])

Я получил false.
Как это может быть на Земле?

ОБНОВЛЕНО
Мой класс Column имеет функции GetHashCode или Equals.Вот их реализации:

public bool Equals(Column other)
{
    if (ReferenceEquals(null, other)) return false;
    if (ReferenceEquals(this, other)) return true;
    return other.Id == Id && Equals(other.Name, Name) && Equals(other.Type, Type) && Equals(other.MainColumn, MainColumn) && Equals(other.childColumns, childColumns);
}

public override bool Equals(object obj)
{
    if (ReferenceEquals(null, obj)) return false;
    if (ReferenceEquals(this, obj)) return true;
    if (obj.GetType() != typeof (Column)) return false;
    return Equals((Column) obj);
}

public override int GetHashCode()
{
    unchecked
    {
        int result = Id;
        result = (result*397) ^ (Name != null ? Name.GetHashCode() : 0);
        result = (result*397) ^ Type.GetHashCode();
        result = (result*397) ^ (MainColumn != null ? MainColumn.GetHashCode() : 0);
        result = (result*397) ^ (childColumns != null ? childColumns.GetHashCode() : 0);
        return result;
    }
}

public static bool operator ==(Column left, Column right)
{
    return Equals(left, right);
}

public static bool operator !=(Column left, Column right)
{
    return !Equals(left, right);
}

Ответы [ 2 ]

6 голосов
/ 22 июня 2011

Это не общая проблема, но что-то специфическое для вашего кода.

ОБНОВЛЕНИЕ:
Хеш-код ключа словаря не должен изменяться.Это не относится к вашему классу Column, поскольку, как только изменяется любое из его свойств, изменяется и хеш-код.
Документация :

Пока объект используется в качестве ключа в Словаре, он не должен изменяться каким-либо образом, который влияет на его хеш-значение.

Фон этого следующий: словарь получает и сохраняетхэш-код ключа в момент его добавления.Если после этого хеш-код ключа изменился, он отличается от сохраненного хеш-кода, и объект не будет рассматриваться как равный первоначально вставленному ключу.

2 голосов
/ 22 июня 2011

Если Dictionary<Column, string> верно, то я думаю, это потому, что тип Column не совместим с тем, как Dictionary<TKey, TValue> проверяет равенство - что основано на сравнении через GetHashCode и Equals - и я предполагаю, что что тип Column не реализует их.

Измените тип ключа словаря на более подходящий для сравнения и равенства. В идеале используйте строку, полученную из имени столбца.

Обновление

Исходя из вашего обновления кода, я предполагаю, что что-то в столбце изменилось с тех пор, как оно вошло в словарь, что приводит к тому, что его «живой» хеш-код изменится по сравнению с тем, каким он был при первом добавлении в Словарь - так, чтобы это может быть любое изменение в Id, Name, Type, MainColumn или ChildColumns, которое вызывает изменение их хэш-кодов.

...