2011-01-04 23 views
15

Usando esta claseC# hashset Contiene no únicos objetos

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(); 
    } 
} 

Y esto 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(); 

tengo la respuesta 2, cuando seguramente debe ser 1. ¿Hay una manera de solucionar este problema entonces mi HashSet contiene solo objetos únicos?

Gracias, Ash.

+6

No ha reemplazado 'Equals'. – Ani

Respuesta

25

El tipo HashSet<T> ultamitely utiliza igualdad para determinar si 2 objetos son iguales o no. En el tipo Foo, solo ha anulado GetHashCode y no hay igualdad. Esto significa que las comprobaciones de igualdad regresarán por defecto al Object.Equals que usa igualdad de referencia. Esto explica por qué ve varios elementos en el HashSet<Foo>. Para solucionar esto, deberá anular Equals en el tipo Foo.

public override bool Equals(object obj) { 
    var other = obj as Foo; 
    if (other == null) { 
    return false; 
    } 
    return c1 == other.c1 && c2 == other.c2; 
} 
+3

+1 porque es correcto, pero se puede agregar que los valores hash devueltos por 'GetHashCode' pueden colisionar para diferentes valores, razón por la cual la comparación del código hash no garantiza la igualdad de los objetos en general. – Lucero

7

Debe sobrescribir el método Equals. Solo GetHashCode no es suficiente.

4

También debe sobrescribir el método equals. La razón de esto es que se permite que el código hash colisione para dos objetos que no son iguales. De lo contrario, no funcionará.

public override bool Equals(Object obj) 
{ 
    Foo otherObject = obj as Foo; 
    return otherObject != null && otherObject.c1 == this.c1 && otherObject.c2 == this.c2; 
} 
+0

La expresión 'local.Equals (null)' debería devolver 'false' no' true' – JaredPar

+0

Es cierto, simplemente lo escribí rápido para mí :). –

Cuestiones relacionadas