Словарь класса в C # - Равенство двух объектов - PullRequest
4 голосов
/ 04 января 2011

У меня есть класс с именем Class1 Я переопределяю его функцию Equals Теперь у меня есть экземпляр словаря И я добавил к нему экземпляр Class1 с именем OBJ1. У меня есть другой экземпляр Class1 с именем OBJ2. код возвращает истину для OBJ1.Equals (OBJ2). Но я не могу найти OBJ2 в словаре.

Вот псевдокод

Class1 OBJ1 = new Class1(x, y, z);
Class1 OBJ2 = new Class1(a, b, c);
Dictionary<Class1, int> dic1 = new Dictionary<Class1, int>();
dic1.Add(OBJ1, 3);
OBJ1.Equals(OBJ2) -------------> return true
Dictionary.ContainsKey(OBJ2) --------------> return false

почему это происходит? любая помощь будет приветствоваться

Ответы [ 7 ]

13 голосов
/ 04 января 2011

2 возможности:

  1. GetHashCode не был корректно переопределен.Возможно, вы захотите взглянуть на Почему важно переопределить GetHashCode, когда метод Equals переопределен в C #?
  2. OBJ1 был мутирован после добавления в словарь вспособ, который влияет на его хэш-код.В этом случае корзина, в которой он находится, больше не будет правильной - ContainsKey закончится поиском его в другом ведре.

С Dictionary<TKey, TValue>:

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

12 голосов
/ 04 января 2011

Скорее всего, вы не переопределили GetHashCode в соответствии с Equals.

Для контракта GetHashCode требуется, чтобы, если OBJ1.Equals(OBJ2) вернул true, OBJ1.GetHashCode() должен вернутьто же значение, что и OBJ2.GetHashCode().

IIRC, вы получите ошибку компилятора (или хотя бы предупреждение), если переопределите Equals без переопределения GetHashCode().

Другая возможностьчто вы на самом деле не overridden Equals, но перегружены , добавив новую подпись, например

public bool Equals(Class1 other)

В общем, чтобы обеспечить «естественное» сравнение равенства значенийвам следует:

  • Переопределить равно (объект)
  • Переопределить GetHashCode
  • Настоятельно рассмотреть возможность реализации IEquatable<T>
  • Рассмотреть возможность перегрузки == и! =
4 голосов
/ 04 января 2011

Вы, вероятно, не переопределяете GetHashcode в своем классе. Когда вы переопределяете Equals, вы также должны переопределить GetHashcode, иначе словарь не будет работать для вас.

3 голосов
/ 04 января 2011

Убедитесь, что Class1 переопределяет GetHashCode (). Возврат из этого метода - это первое, что проверяется при сравнении равенства. Реализация по умолчанию уникальна для каждого объекта.

3 голосов
/ 04 января 2011

Вам также необходимо переопределить GetHashCode, но также не забывайте, что вам может понадобиться передать пользовательский Comparer и в конструктор Dictionary , как указано в этом вопросе SO

3 голосов
/ 04 января 2011

Вы переопределили GetHashCode либо?

3 голосов
/ 04 января 2011

Вы также переопределяли GetHashCode? Можете ли вы показать реализацию метода Equals?

...