C# - Liste .Remove () löscht immer das erste Objekt auf der Liste
-
07-07-2019 - |
Frage
Arbeiten in Visual Studio 2008 (C#) ... Ich verwende eine Listensammlung, um Instanzen meiner benutzerdefinierten Klasse (Shift) zu speichern.
Ich möchte eine bestimmte Verschiebung aus der Liste löschen, indem ich die Methode entfernen.
Aber list.remove () löscht immer das erste Element, den es findet.
Ich habe die iComparable -Schnittstelle für meine Verschiebung implementiert, ich dachte, dies würde ausreichen, dann habe ich eine Implementierung von iEqualityComparer hinzugefügt, und es hat immer noch keinen Einfluss.
Hier ist der Auszug mit meiner Implementierung:
Region IComenable Mitglieder
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
Region IequalityComparer -Mitglieder
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
Und doch immer noch - wenn die Liste zwei Schichten enthält, sagen Sie "8:00 - 15:00"; "12:00 - 16:00", rufen Sie an ("12: 00-16: 00"). Es führt zu "8:00 - 15:00", und letzteres bleibt in der Sammlung!
Was ist hier los? Danke
Lösung
Sie können überschreiben object.GetHashCode
und 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);
}
Sie sollten wahrscheinlich auch einen Null -Check -in machen Equals(x, y)
.
Andere Tipps
IComparable
wird normalerweise nicht zum Vergleich der Gleichheit verwendet (es wird zur Bestellung verwendet), also List<T>.Remove()
ignoriert es.
IEqualityComparer
ist kein Äquivalent von IComparable
Für Gleichstellungszwecke. Es soll von a implementiert werden Vergleichsobjekt - Das heißt ein Objekt, das vergleicht andere Objekte für Gleichheit. Wenn Sie möchten, dass Gleichstellungsvergleiche Ihrer Klasse inhärent sind, müssen Sie lieber implementieren IEquatable<T>
. Oder einfach überschreiben Object.Equals()
und Object.GetHashCode()
in Ihrer Klasse, ohne Schnittstellen zu implementieren.
Verwendungen entfernen EqualityComparer<T>.Default
Um die Gleichheit zu bestimmen und zu entfernen, welches Objekt verwendet werden soll, welche verwendet IEquatable<T>
Wenn es in Ihrem Objekt implementiert ist, verwendet es ansonsten die Referenzgleichheit.
Sie haben zwei Optionen, um das gewünschte Verhalten zu erhalten:
1) Verschiebung implementieren IEquatable<T>
(Nicht nur überschreiben Objekte.Equals oder erstellen Sie die Methode, sondern machen Sie auch Verschiebung - Shift : IEquatable<Shift>
)
2) Verwendung List<T>.RemoveAt
Mit dem Beispiel, das Sie angegeben haben, rufen Sie an:
List<Shift>.Remove("12:00 - 16:00");
"12:00 - 16:00"
In diesem Fall ist a String
Wert und keine tatsächliche Shift
Objekt. Stellen Sie sicher, dass dies in Ihrem CompareTo
Methode, dass Ihr Code das ordnungsgemäß wirkt String
Wert zu a Shift
Objekt. Ansonsten, wenn es die Anfangszeiten vergleicht ... könnten die Dinge Heuwirren gehen.