C # - Elenco < T > .Remove () elimina sempre il primo oggetto nell'elenco
-
07-07-2019 - |
Domanda
Lavorare in Visual Studio 2008 (C #) ... Uso una raccolta Elenco per memorizzare istanze della mia classe personalizzata (Maiusc).
Voglio eliminare un certo spostamento dall'elenco usando il metodo Remove.
Ma List.Remove () elimina sempre il primo elemento che trova.
Ho implementato l'interfaccia IComparable per il mio Shift, ho pensato che sarebbe bastato, quindi ho aggiunto un'implementazione di IEqualityComparer e non ha ancora alcun effetto.
Ecco l'estratto della mia implementazione:
Membri IComparable della regione
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
regione IEqualityComparer Members
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
Eppure, ancora - quando l'Elenco contiene due turni, dì "8: 00 - 15: 00"; "12: 00 - 16: 00", chiamando Rimuovi ("12: 00-16: 00") si ottiene "8: 00 - 15: 00"; viene rimosso e quest'ultimo rimane nella raccolta!
Cosa c'è che non va qui? Thx
Soluzione
Puoi ignorare object.GetHashCode
e 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);
}
Probabilmente dovresti anche fare un controllo nullo in Equals (x, y)
.
Altri suggerimenti
IComparable
non viene normalmente utilizzato per confrontare per l'uguaglianza (è usato per l'ordinamento), quindi List < T > .Remove ()
lo ignora.
IEqualityComparer
non equivale a IComparable
a fini di uguaglianza. Dovrebbe essere implementato da un oggetto comparatore - cioè un oggetto che confronta altri oggetti per uguaglianza. Se desideri che i confronti di uguaglianza siano inerenti alla tua classe, devi piuttosto implementare IEquatable < T >
. Oppure sovrascrivi Object.Equals ()
e Object.GetHashCode ()
sulla tua classe, senza implementare alcuna interfaccia.
Rimuovi usa EqualityComparer < T > .Default
per determinare l'uguaglianza e scegliere quale oggetto rimuovere, che utilizzerà IEquatable < T >
se è implementato sul tuo oggetto, altrimenti , utilizzerà l'uguaglianza di riferimento.
Hai due opzioni per ottenere il comportamento che desideri:
1) Imposta Shift come IEquatable < T >
(non solo sovrascrivere Object.Equals o creare il metodo, ma fare Shift - Shift: IEquatable < Shift >
)
2) Usa Elenco < T > .RemoveAt
Con l'esempio fornito, stai chiamando:
List<Shift>.Remove("12:00 - 16:00");
" 12: 00 - 16: 00 "
in questo caso, è un valore String
e non un vero oggetto Shift
. Assicurati che nel tuo metodo CompareTo
il tuo codice esegua correttamente il casting del valore String
su un oggetto Shift
. Altrimenti, quando confronta i tempi di inizio ... le cose potrebbero andare in tilt.