2013-05-15 18 views
9

Próbuję posortować listę obiektów przy użyciu List.Sort(), ale w środowisku wykonawczym mówi mi, że nie może porównywać elementów w tablicy.Dlaczego nie mogę używać klasy IComparable <T> w klasie przodków i porównywać klas potomnych?

Nie można porównać dwa elementy w tablicy

struktury klasowej:

public abstract class Parent : IComparable<Parent> { 
    public string Title; 
    public Parent(string title){this.Title = title;} 

    public int CompareTo(Parent other){ 
     return this.Title.CompareTo(other.Title); 
    } 
} 

public class Child : Parent { 
    public Child(string title):base(title){} 
} 

List<Child> children = GetChildren(); 
children.Sort(); //Fails with "Failed to compare two elements in the array." 

Dlaczego nie mogę porównać podklasy bazy, która implementuje IComparable<T>? Prawdopodobnie czegoś brakuje, ale nie rozumiem, dlaczego nie powinno to być dozwolone.

Edycja: należy wyjaśnić, że jestem kierowanie .NET 3.5 (SharePoint 2010)

Edit2: .NET 3.5 jest problem (patrz odpowiedź poniżej).

+2

Ponieważ wydaje się, że jest to wyjątek środowiska wykonawczego, być może jedno z Twoich dzieci ma "Tytuł" o wartości NULL? A może na twojej liście jest null? – nvoigt

+0

http://stackoverflow.com/questions/1658661/failed-to-compare-two-elements-in-the-array –

+3

Działa na mnie z .NET 4, ale [** nie na ideone **] (http: //ideone.com/rZ0rVL), jakiej wersji .NET używasz? –

Odpowiedz

11

Zakładam, że jest to wersja .NET przed .NET 4.0; po .NET 4.0 jest IComparable<in T> i powinno działać OK w wielu przypadkach - wymaga to jednak zmiany wariancji 4,0

lista jest List<Child> - tak sortowania będzie starał się wykorzystać zarówno IComparable<Child> lub IComparable - ale żadna z nich jest wdrożony. Można realizować IComparable na poziomie Parent, może:

public abstract class Parent : IComparable<Parent>, IComparable { 
    public string Title; 
    public Parent(string title){this.Title = title;} 

    int IComparable.CompareTo(object other) { 
     return CompareTo((Parent)other); 
    } 
    public int CompareTo(Parent other){ 
     return this.Title.CompareTo(other.Title); 
    } 
} 

które stosują tę samą logikę poprzez object.

+0

Wiem, że mogę używać IComparable, ale tak naprawdę chcę tylko wspierać porównywanie dwóch klas wywodzących się z Parent. Dziecko jest przecież rodzicem, więc nie rozumiem, dlaczego nie mogę go po prostu wdrożyć tak jak powyżej. – Thomas

+0

Tak, ale dlaczego nie jest możliwe użycie porównywalnika klasy macierzystej? Gdyby to była osobna funkcja statyczna, byłoby to możliwe. Czy kompilator nie powinien szukać porównywarek bazowych? To może być możliwe, ale prawdopodobnie nie jest zaimplementowane ... –

+0

Właściwie kod działa dla mnie i poprawnie sortuje. Nie działa to oczywiście, jeśli usunięto implementację 'IComparable '. * Aktualizacja *: To zdecydowanie ze względu na .NET 4. – Jon