HashSets no mantiene los elementos únicos si muta su identidad

Cuando se trabaja conHashSets en C #, recientemente me encontré con un problema molesto:HashSets no garantizamos la unicidad de los elementos; no son conjuntos. Lo que sí garantizan es que cuandoAdd(T item) se llama el elemento no se agrega si para cualquier elemento en el conjuntoitem.equals(that) estrue. Esto ya no es válido si manipulas elementos que ya están en el conjunto. Un pequeño programa que demuestra (copypasta desde mi 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();
  }
}

Felizmente manipulará los elementos de la colección para que sean iguales, solo los filtrará cuando se cree un nuevo HashSet. ¿Qué es aconsejable cuando quiero trabajar con conjuntos en los que necesito saber que las entradas son únicas? Desplazar mi cuenta, donde Agregar (elemento T) agrega una copia fuera del elemento y el enumerador enumera las copias de los elementos contenidos. Esto presenta el desafío de que cada elemento contenido debe ser copiable en profundidad, al menos en sus elementos que influyen en su igualdad.

Otra solución sería rodar los suyos, y solo acepta elementos que implementan INotifyPropertyChanged, y tomar medidas en el evento para volver a verificar la igualdad, pero esto parece ser muy limitante, por no mencionar un montón de trabajo y pérdida de rendimiento bajo el capó .

Otra solución posible en la que pensé es asegurarme de que todos los campos estén leídos o constantes en el constructor. Todas las soluciones parecen tener grandes inconvenientes. ¿Tengo otras opciones?

Respuestas a la pregunta(3)

Su respuesta a la pregunta