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

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top