Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > HashSet Contains


Автор: N1ko 8.12.2012, 00:43
Не могу понять поведение метода Contains. Почему после добавления элемента в ХэшСет и выплнения метода Contains первый раз, возвращает True (вызывается и GetHashCode и Equals). После того как я меняю имя  fi.Name = "AA"; Contains уже возвращает False. (вызывается только GetHashCode)Что не так? 

Ps Добавление второго параметра типа IEqualityComparer в метод Contains не предлагать. Можно ли придумать более гибкое решение посредством изменения самого типа?

Код

        private void button1_Click(object sender, EventArgs e)
        {
            var favourites = new HashSet<FavouriteItem>();
            var fi = new FavouriteItem { Id = 1, Name = "A" };
            favourites.Add(fi);
            if (favourites.Contains(fi))
            {
             MessageBox.Show("Exist!!!")
            }
            fi.Name = "AA";
            if (favourites.Contains(fi))
            {
             MessageBox.Show("It doesn't exist? o_O")
            }
        }
        public class FavouriteItem
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public override bool Equals(object obj)
            {
                FavouriteItem test = obj as FavouriteItem;
                return Id.Equals(test.Id) && Name.Equals(test.Name);
            }
            public override int GetHashCode()
            {
                return (Name + Id).GetHashCode();
            }
        }

Автор: VSB 9.12.2012, 22:16
Ну дак всё правильно, сначала сравниваются хеши, если равны  - то сравниваются сами объекты

Автор: mihryak 10.12.2012, 14:02
При добавлении в коллекцию хэш-код объекта запоминается и сохраняется для дальнейшего использования.
В результате объект у тебя знает, что изменился (GetHashCode учитывает Name), а HashSet - не в курсе, он ждёт именно объекта со свойствами {1, "A"}.
И странно ожидать другого - ты, заоверрайдив GetHashCode, сказал, что тебя интересуют не инстансы, а их конкретные свойства.
Обойти такое поведение можно разными способами разной степени корявости, но проблема тут в том, что тебе стоит разобраться сперва, нужно ли тебе сравнивать инстансы или их свойства.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)