2009-02-02 5 views
7

Ok, quindi ho uno scenario simile al codice seguente, ho una classe genitore che implementa IComparable e una classe figlia.Ho un problema con IComparable e il metodo di ordinamento della raccolta

class Parent : IComparable<Parent> 
class Child : Parent 

Child a = new Child(); 
Child b = new Child(); 
a.CompareTo(b); 

Ora le opere di cui sopra bene, posso confrontare due del bambino oggetti tra di loro non è un problema

List<Child> l = new List<Child>(); 
l.Add(b); 
l.Add(a); 
l.Sort(); 

È possibile che non riesce però con un'InvalidOperationException. Qualcuno può spiegare perché questo tipo non funziona quando la classe figlio implementa l'interfaccia IComparable, o almeno mi sembra che lo faccia.

Va bene qui è la mia implementazione CompareTo per la mia classe di padre effettivo

public int CompareTo(IDType other) 
{ 
     return this.Name.ToString().CompareTo(other.ToString()); 
} 
+0

il tuo campione dice "nuova lista ()", che sto cercando di indovinare è un errore di battitura ... qual è il tipo generico reale nella lista che si sta creando? –

+0

Oh scusa si era un errore di battitura, avevo la lista l = nuova lista (); Penso che sia abbastanza ovvio quale lista di tipi generici stavo creando. – CalvinR

+0

Possiamo vedere il codice dalla tua implementazione IComparable? –

risposta

6

tuo tipo implementa IComparable<Parent> piuttosto che IComparable<Child>. Come dice il MSDN docs for Sort, invierà InvalidOperationException se "il comparatore di comparazione predefinito (T) .Default non riesce a trovare un'implementazione dell'interfaccia generica IComparable (T) o dell'interfaccia IComparable per il tipo T." E infatti non può, dove T è figlio. Se provi a renderlo un List<Parent> potresti trovare che va bene.

MODIFICA: In alternativa (e preferibilmente, IMO) attuare IComparable<Child>. Al momento non è affatto chiaro che un bambino possa essere sensibilmente comparato con un altro bambino. Implementazione IComparable<Child> - anche se l'implementazione si limita a implementare la base - pubblicizza la comparabilità.

+0

Nessun mio paragone funziona bene, sto semplicemente usando la funzione di confronto di una variabile membro della stringa che è memorizzata nella classe genitore. – CalvinR

+0

La risposta è stata cambiata completamente adesso, dopo aver controllato qualcos'altro :) –

+1

L'uomo che è una spazzatura assoluta, funziona bene se implemento il non-generico IComparable nella classe genitore. – CalvinR

3

Ho provato e ho fatto lo stesso errore. La mia ipotesi è che, poiché hai uno List<Child>, sta cercando qualcuno che implementa IComparable<Child>, non IComparable<Parent>.

Se si modifica la raccolta su List<Parent>, le cose sembrano funzionare. In alternativa, imposti l'implementazione di Child IComparable<Child> (e può delegare solo all'implementazione di Parent).

+0

Sì, sfortunatamente non cambierò le mie collezioni per lavorare in questo modo in qualsiasi momento, quindi suppongo che dovrò solo implementare IC non comparabile generico o semplicemente implementare quello generico in ciascuna delle classi che voglio ordinare . – CalvinR

3

La mia ipotesi è che abbia qualcosa a che fare con la covarianza/controvarianza. Il motivo per cui dico che è perché questo non riesce come lei ha detto:

public class Parent : IComparable<Parent> 
    { 
     public int Age { get; set; } 


     public int CompareTo(Parent other) 
     { 

      return this.Age.CompareTo(other.Age); 
     } 

    } 

    public class Child : Parent 
    { 
     public string Name { get; set; } 
    } 

Tuttavia, quando ho cambiato il genitore per l'attuazione del IComparable non generico e fatto questo, ha funzionato:

public class Parent : IComparable 
    { 
    public int Age { get; set; } 


    public int CompareTo(object other) 
    { 
     Parent p = other as Parent; 
     return this.Age.CompareTo(p.Age); 
    } 

} 

    public class Child : Parent 
    { 
     public string Name { get; set; } 
    } 

codice ho provato con:

List<Child> c = new List<Child>(); 
    c.Add(new Child { Age = 10, Name = "Alex" }); 
    c.Add(new Child { Age = 6, Name = "Jack" }); 
    c.Add(new Child { Age = 15, Name = "Bob" }); 

    c.Sort(); 
+0

Sì, ho trovato la stessa cosa, speravo solo di poter ancora usare la forma generica di Icomparable. – CalvinR

Problemi correlati