2013-05-15 19 views
9

Ich versuche, eine Liste von Objekten mit List.Sort( zu sortieren, aber zur Laufzeit sagt es mir, dass es Elemente im Array nicht vergleichen kann.Warum kann ich IComparable <T> nicht für die Vorgängerklasse verwenden und untergeordnete Klassen vergleichen?

fehlgeschlagen

Klasse Struktur zwei Elemente im Array vergleichen:

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." 

Warum kann ich nicht vergleichen Subklassen von einer Basis, die IComparable<T> implementiert? Ich verpasse wahrscheinlich etwas, aber ich kann nicht sehen, warum das nicht erlaubt sein sollte.

Edit: Sollte klarstellen, dass ich .NET 3.5 (Sharepoint 2010)

EDIT2 bin Targeting: .NET 3.5 das Problem ist (siehe unten beantworten).

+2

Da dies eine Laufzeitausnahme zu sein scheint, hat vielleicht einer Ihrer Kinder einen 'Title' von null? Oder vielleicht gibt es eine Null in Ihrer Liste? – nvoigt

+0

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

+3

Es funktioniert für mich mit .NET 4 aber [** nicht auf ideone **] (http: //ideone.com/rZ0rVL), welche .NET-Version verwenden Sie? –

Antwort

11

Ich nehme an, das ist eine .NET-Version vor .NET 4.0; nach 4,0 .NET ist es IComparable<in T> und soll in vielen Fällen OK arbeiten - aber dies erfordert die Varianz Änderungen in 4.0

Die Liste List<Child> ist - so das Sortieren entweder IComparable<Child> oder IComparable zu verwenden versuchen - aber keiner von denen ist implementiert. Sie könnten IComparable am Parent Ebene umzusetzen, vielleicht:

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); 
    } 
} 

, die die gleiche Logik über object gelten.

+0

Ich weiß, dass ich IComparable verwenden kann, aber ich möchte wirklich nur zwei Klassen vergleichen, die von Parent abgeleitet sind. Das Kind ist nach allem ein Elternteil, also verstehe ich nicht, warum ich es nicht einfach wie oben implementieren kann. – Thomas

+0

Ja, aber warum ist es nicht möglich, Elternvergleiche zu verwenden? Wenn es eine separate statische Funktion wäre, wäre es möglich. Sollte der Compiler nicht nach Basisklassenvergleichern suchen? Es wäre möglich, aber wahrscheinlich ist nicht implementiert ... –

+0

Eigentlich funktioniert der Code für mich und sortiert korrekt. Es funktioniert natürlich nicht, wenn die IComparable Implementierung entfernt wird. * Update *: Es ist definitiv wegen .NET 4. – Jon