2009-09-16 13 views
5

Trabajando en Visual Studio 2008 (C#) ... Utilizo una colección de lista para almacenar instancias de mi clase personalizada (Shift).C# - Lista <T> .Remove() siempre elimina el primer objeto en la lista

Quiero eliminar un cierto turno de la lista usando el método Eliminar.

Pero List.Remove() siempre borra el primer elemento que encuentra.

Implementé la interfaz IComparable para mi Shift, pensé que esto sería suficiente, luego agregué una implementación de IEqualityComparer, y todavía no tiene ningún efecto.

Este es el pasaje con mi aplicación:

región Miembros IComparable

public int CompareTo(object obj) 
    { 
     Shift s1 = this; 
     Shift s2 = (Shift)obj; 
     if (s1.start.time != s2.start.time) 
      return s1.start.CompareTo(s2.start); 
     else 
      return s1.end.CompareTo(s2.end); 
    } 

endRegion

región IEqualityComparer miembros

public bool Equals(Shift x, Shift y) 
    { 

     if ((x.opening) != (y.opening)) return false; 
     if ((x.closing) != (y.closing)) return false; 
     if (!x.opening) if (x._start != y._start) return false; 
     if (!x.closing) if (x._end != y._end) return false; 
     if (x.when != y.when) return false; 
     if (x.day != y.day) return false; 
     if (x.EmployeeID != y.EmployeeID) return false; 
     return true; 
    } 

    public int GetHashCode(Shift obj) 
    { 
     return obj.ToString().ToLower().GetHashCode(); 
    } 

endRegion

Y, sin embargo, aún - cuando la Lista contiene dos turnos, diga "8:00 - 15:00"; "12:00 - 16:00", llamando a Eliminar ("12: 00-16: 00") los resultados en "8:00 - 15:00" se eliminan, y el último permanece en la colección!

¿Qué pasa aquí? Thx

Respuesta

11

Puede anular object.GetHashCode y object.Equals:

public override bool Equals(object obj) 
{ 
    if(obj == null) 
    { 
     return false; 
    } 
    return Equals(this, obj as Shift); 
} 

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

También debe probablemente hacer una verificación nulo en Equals(x, y).

+0

También debe devolver false si obj.GetType()! = GetType(), de lo contrario corre el riesgo de realizar comprobaciones de igualdad contra subclases que pueden tener algoritmos más refinados. –

+0

-1, no sobrecargó object.GetHashCode(), implementó IEqualityComparer .GetHashCode (T). –

+0

@csharptest buen lugar, gracias –

0

Quitar utiliza EqualityComparer<T>.Default para determinar la igualdad y elegir cuál es el objeto de eliminar, que utilizará IEquatable<T> si se implementa en el objeto, de lo contrario, se utilizará la igualdad de referencia.

usted tiene dos opciones para conseguir el comportamiento que desea:

1) Hacer cambio de implemento IEquatable<T> (no sólo anulan Object.equals o hacer que el método, pero hacen Shift - Shift : IEquatable<Shift>)

2) Uso List<T>.RemoveAt

0

Con el ejemplo que nos ha facilitado, que está llamando:

List<Shift>.Remove("12:00 - 16:00"); 

"12:00 - 16:00" en este caso, es un valor String y no un objeto real Shift. Asegúrese de que en su método CompareTo su código está arrojando correctamente el valor String a un objeto Shift. De lo contrario, cuando se comparan los tiempos de inicio ... las cosas podrían volverse locas.

+0

Justin, de hecho, realmente no paso un parámetro de cadena, esto fue una especie de "pseudocódigo" de mi parte solo para mostrar el concepto. Lo siento si eso fue ambiguo –

3

IComparable normalmente no se usa para comparar por igualdad (se usa para ordenar), por lo que List<T>.Remove() lo ignora.

IEqualityComparer no es un equivalente de IComparable con fines de igualdad. Se supone que debe ser implementado por un objeto comparador - es decir, un objeto que compara otros objetos por igualdad. Si desea que las comparaciones de igualdad sean inherentes a su clase, entonces necesita implementar IEquatable<T>. O simplemente anule Object.Equals() y Object.GetHashCode() en su clase, sin implementar ninguna interfaz.

+0

En realidad Object.Equals() funciona justo! Esa parece ser la opción más simple de todas. Gracias –

Cuestiones relacionadas