HashSets не сохраняет элементы уникальными, если вы изменяете их идентичность

При работе сHashSets в C # я недавно столкнулся с досадной проблемой:HashSets не гарантируют уникальность элементов; они не наборы. Они гарантируют, что когдаAdd(T item) называется элемент не добавляется, если для какого-либо элемента в набореitem.equals(that) являетсяtrue, Это больше не действует, если вы манипулируете элементами, уже находящимися в наборе. Небольшая программа, которая демонстрирует (copypasta из моего Linqpad):

void Main()
{
    HashSet<Tester> testset = new HashSet<Tester>();
    testset.Add(new Tester(1));
    testset.Add(new Tester(2));
    foreach(Tester tester in testset){
      tester.Dump();
    }
    foreach(Tester tester in testset){
      tester.myint = 3;
    }
    foreach(Tester tester in testset){
      tester.Dump();
    }
    HashSet<Tester> secondhashset = new HashSet<Tester>(testset);
    foreach(Tester tester in secondhashset){
      tester.Dump();
    }
}

class Tester{
  public int myint;

  public Tester(int i){
    this.myint = i;
  }

  public override bool Equals(object o){
    if (o== null) return false;
    Tester that = o as Tester;
    if (that == null) return false;
    return (this.myint == that.myint);
  }

  public override int GetHashCode(){
    return this.myint;
  }

  public override string ToString(){
    return this.myint.ToString();
  }
}

Он с радостью манипулирует элементами в коллекции, чтобы они были равными, только отфильтровывая их при создании нового HashSet. Что целесообразно, когда я хочу работать с наборами, где мне нужно знать, что записи уникальны? Прокрутите мой, где Add (T item) добавляет копию элемента, а перечислитель перечисляет копии содержащихся элементов? Это создает проблему, заключающуюся в том, что каждый содержащийся элемент должен быть глубоко копируемым, по крайней мере, в его элементах, которые влияют на его равенство.

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

Еще одно возможное решение, о котором я подумал, - убедиться, что все поля доступны только для чтения или являются постоянными в конструкторе. Все решения, похоже, имеют очень большие недостатки. У меня есть другие варианты?

Ответы на вопрос(3)

Ваш ответ на вопрос