C# HashSet Generic допускает дублирование

Читая HashSet в MSDN, он говорит, что с HashSet<T>, если T реализует IEquatable<T>, то HashSet использует это для IEqualityComparer<T>.Default.

Итак, пусть класс Person:

public class Person : IEquality<Person>
{
    private string pName;
    public Person(string name){ pName=name; }
    public string Name
    {
        get { return pName; }
        set
        {
            if (pName.Equals(value, StringComparison.InvariantCultureIgnoreCase))
            {
              return;
            }
            pName = value;
        }
    }

    public bool Equals(Person other)
    {
        if(other==null){return false;}
        return pName.Equals(other.pName, StringComparison.InvariantCultureIgnoreCase);
    }

    public override bool Equals(object obj)
    {
        Person other = obj as Person;
        if(other==null){return false;}
        return Equals(other);
    }

    public override int GetHashCode(){return pName.GetHashCode();}

    public override string ToString(){return pName;}
}

Итак, давайте определим в другом классе или основной функции:

HashSet<Person> set = new HashSet<Person>();
set.Add(new Person("Smith"); // return true
Person p = new Person("Smi");
set.Add(p); // return true
p.Name = "Smith"; // no error occurs

И теперь у вас есть 2 объекта Person в HashSet с одинаковым именем (так что есть «Равные»).

HashSet позволяет размещать повторяющиеся объекты.


person DvptUml    schedule 05.10.2012    source источник


Ответы (1)


HashSet позволяет размещать повторяющиеся объекты.

Это не позволяет вам помещать дубликаты объектов. Проблема в том, что вы мутируете объект после его добавления.

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

person Reed Copsey    schedule 05.10.2012
comment
Согласитесь, вам следует рассмотреть возможность удаления установщика для Person, чтобы сделать Person неизменяемым и предотвратить это. - person neontapir; 05.10.2012