C # Hashset содержит неуникальные объекты - PullRequest
15 голосов
/ 05 января 2011

Используя этот класс

public class Foo
{
    public string c1, c2;

    public Foo(string one, string two)
    {
        c1 = one;
        c2 = two;
    }

    public override int GetHashCode()
    {
        return (c1 + c2).GetHashCode();
    }
}

И этот HashSet

HashSet<Foo> aFoos = new HashSet<Foo>();
Foo aFoo = new Foo("a", "b");

aFoos.Add(aFoo);
aFoos.Add(new Foo("a", "b"));

label1.Text = aFoos.Count().ToString();

Я получаю ответ 2, когда наверняка это должно быть 1. Есть ли способ исправить это, так что мой HashSetсодержит только уникальные объекты?

Спасибо, Эш.

Ответы [ 3 ]

26 голосов
/ 05 января 2011

Тип HashSet<T> в конечном итоге использует равенство, чтобы определить, равны ли 2 объекта или нет. В типе Foo вы только переопределяете GetHashCode, а не равенство. Это означает, что проверки на равенство по умолчанию вернутся к Object.Equals, который использует равенство ссылок. Это объясняет, почему вы видите несколько элементов в HashSet<Foo>.

Чтобы это исправить, вам нужно переопределить Equals в типе Foo.

public override bool Equals(object obj) { 
  var other = obj as Foo;
  if (other == null) {
    return false;
  }
  return c1 == other.c1 && c2 == other.c2;
}
7 голосов
/ 05 января 2011

Вам необходимо переопределить метод Equals. Только GetHashCode недостаточно.

4 голосов
/ 05 января 2011

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

public override bool Equals(Object obj)
{ 
   Foo otherObject = obj as Foo;
   return otherObject != null && otherObject.c1 == this.c1 && otherObject.c2 == this.c2;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...