2009-09-16 16 views
5

Travailler dans Visual Studio 2008 (C#) ... J'utilise une collection de listes pour stocker des instances de ma classe personnalisée (Maj).C# - Liste <T> .Remove() supprime toujours le premier objet de la liste.

Je souhaite supprimer un certain décalage de la liste en utilisant la méthode Remove. Mais List.Remove() supprime toujours le premier élément qu'il trouve.

J'ai implémenté l'interface IComparable pour mon Shift, j'ai pensé que ce serait suffisant, puis j'ai ajouté une implémentation de IEqualityComparer, et cela n'a toujours aucun effet.

est ici l'extrait avec ma mise en œuvre:

région IComparable Membres

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

région IEqualityComparer Membres

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

Et pourtant, encore - quand la liste contient deux équipes, dites "8:00 - 15:00"; "12:00 - 16:00", l'appel de Remove ("12: 00-16: 00") se traduit par "8:00 - 15:00" se retirer, et le dernier reste dans la collection!

Quel est le problème ici? Thx

Répondre

11

Vous pouvez remplacer object.GetHashCode et 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); 
} 

Vous devriez aussi probablement faire un chèque nul dans Equals(x, y).

+0

Vous devriez aussi retourner false si obj.GetType()! = GetType(), sinon vous risquez de faire des contrôles d'égalité contre les sous-classes qui peuvent avoir des algorithmes plus raffinés. –

+0

-1, Il n'a pas surchargé object.GetHashCode(), il a implémenté IEqualityComparer .GetHashCode (T). –

+0

@csharptest bon endroit, merci –

0

Supprimer utilise EqualityComparer<T>.Default pour déterminer l'égalité et choisir l'objet à supprimer, qui utilisera IEquatable<T> s'il est implémenté sur votre objet, sinon, il utilisera l'égalité de référence.

Vous avez deux options pour obtenir le comportement souhaité:

1) arrangent outil IEquatable<T> (pas seulement outrepasser Object.Equals ou faire la méthode, mais faire Shift - Shift : IEquatable<Shift>)

2) Utilisation List<T>.RemoveAt

0

Avec l'exemple que vous avez fourni, vous appelez:

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

"12:00 - 16:00" dans ce cas, est une valeur String et pas un objet réel Shift. Assurez-vous que dans votre méthode CompareTo que vous codez correctement, la valeur String est convertie en objet Shift. Sinon, quand il compare les heures de début ... les choses pourraient devenir détraquées.

+0

Justin, en fait, je ne passe pas vraiment un paramètre de chaîne, c'était une sorte de "pseudo-code" de ma part, juste pour montrer le concept. Désolé si c'était ambigu –

3

IComparable n'est normalement pas utilisé pour comparer l'égalité (il est utilisé pour la commande), donc List<T>.Remove() l'ignore.

IEqualityComparer n'est pas un équivalent de IComparable à des fins d'égalité. Il est censé être implémenté par un objet - c'est-à-dire un objet qui compare d'autres objets pour l'égalité. Si vous souhaitez que les comparaisons d'égalité soient inhérentes à votre classe, vous devez plutôt implémenter IEquatable<T>. Ou simplement remplacer Object.Equals() et Object.GetHashCode() sur votre classe, sans implémenter d'interfaces.

+0

En fait Object.Equals() fonctionne bien! Cela semble être l'option la plus simple de toutes. Je vous remercie –