2009-12-12 18 views
-2

J'implémente IComparable pour trier les objets typés. Ma question est pourquoi est-ce que ça jette type person à int32? Le tableau Sort() semble lancer chaque type dans le tableau au type que j'utilise pour la comparaison.Implémentation de IComparable

Comparable:

public class Person:IComparable 
{ 
    protected int age; 

    public int Age { get; set; } 

    public int CompareTo(object obj) 
    { 
     if(obj is Person) 
     { 
      var person = (Person) obj; 
      return age.CompareTo(person.age); 
     } 
     else 
     { 
      throw new ArgumentException("Object is not of type Person"); 
     } 
    } 
} 

}

class Program 
{ 
    static void Main(string[] args) 
    { 
     Person p1 = new Person(); 
     Person p2 = new Person(); 
     Person p3 = new Person(); 
     Person p4 = new Person(); 

     ArrayList array = new ArrayList(); 

     array.Add(p1.Age = 6); 
     array.Add(p2.Age = 10); 
     array.Add(p3.Age = 5); 
     array.Add(p4.Age = 11); 

     array.Sort(); 

     foreach (var list in array) 
     { 
      var person = (Person) list; //Cast Exception here. 

      Console.WriteLine(list.GetType().ToString()); //Returns System.Int32 
     } 
     Console.ReadLine(); 


    } 
+0

BTW: Si vous êtes sur .Net 3.5, vous n'avez pas besoin d'utiliser Trier() et IComparable. Il existe une nouvelle méthode d'extension appelée OrderBy qui est beaucoup plus facile à utiliser que Sort. –

+4

S'il est sur .Net 3.5 (ou 2.0) il ne devrait vraiment pas utiliser ArrayList, mais Liste . Il n'aurait pas eu ce problème s'il l'avait fait (il aurait eu une erreur de compilation et il aurait probablement compris le problème). –

+0

Pourquoi n'utilisez-vous pas les génériques 'List ' et 'IComparable '? – thecoop

Répondre

11

Votre ligne:

array.Add(p1.Age = 6) 

ajoute le résultat de l'instruction p1.Age = 6 à la ArrayList. C'est la valeur int 6. Rien à voir avec IComparable ou Sort.

+0

Of Coarse ... merci – Nick

1

Vous ajoutez person.Age à votre arraylist, et person.Age est un int.
Vous devriez faire quelque chose comme

Person p1 = new Person(){Age=3}; 
array.Add(p1); 
4

Vous n'êtes pas d'ajouter les personnes au tableau.

p1.Age = 6 

est une affectation et renvoie tout ce qui a été affecté à la variable/propriété (dans ce cas, 6).

Vous devez effectuer les affectations avant de placer les Personnes dans le tableau.

Si vous souhaitez uniquement placer des éléments d'un seul type dans une collection, vous souhaitez utiliser une collection typée plutôt qu'une typographie non typée. Cela aurait pris le problème immédiatement.

7

La meilleure façon de mettre en œuvre IComparable est de mettre en œuvre IComparable<T> et passer les appels à cette mise en œuvre:

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

    public int CompareTo(Person other) 
    { 
    // Should be a null check here... 
    return this.Age.CompareTo(other.Age); 
    } 

    public int CompareTo(object obj) 
    { 
    // Should be a null check here... 
    var otherPerson = obj as Person; 
    if (otherPerson == null) throw new ArgumentException("..."); 
    // Call the generic interface's implementation: 
    return CompareTo(otherPerson); 
    } 
} 
+0

Vous pouvez ajouter if (other == null) return 1; dans votre CompareTo – mayu

+0

@Tymek, bon point, cette implémentation ne gère pas gracieusement les objets d'autres types (collections hétérogènes) ou même les nulls du même type. – Constantin