erhan urun
erhan urun

Reputation: 115

CompareTo() method doesn't work

I have a Class named Person which implement IComparable<int> generic Interface . I have a generic list which contain Person Object and I assign my list to an array and I'm sorting the list but I'm taking the follwing error.

error: {"Failed to compare two elements in the array."}

this is my Person class

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

        public int CompareTo(int other)
        {
            return Age.CompareTo(other);
        }
    }

and this program cs

class Program
{
    static void Main(string[] args)
    {
        List<Person> list2 = new List<Person>();

        list2.Add(new Person() { Age = 80 });
        list2.Add(new Person() { Age = 45 });
        list2.Add(new Person() { Age = 3 });
        list2.Add(new Person() { Age = 77 });
        list2.Add(new Person() { Age = 45 });

        Person[] array = list2.ToArray();
        Array.Sort(array);

        foreach (Person item in array)
        {
            Console.WriteLine(item.Age);
        }

        Console.ReadKey();
    }
}

Upvotes: 2

Views: 2401

Answers (4)

Rahul Singh
Rahul Singh

Reputation: 21795

Use this:-

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

        public int CompareTo(Person other)
        {
            return this.Age.CompareTo(other.Age);
        }
    }

Your custom comparer is wrong! CompareTo() method returns an integer which indicates:-

 0 -> Current instance is equal to the object being compared.
>0 -> Current instance is greater than the object being compared.
<0 -> Current instance is less than the object being compared.

When you call Array.Sort(array); you are actually passing an array object but the problem is you had implemented IComparable of type int.

Upvotes: 2

Paweł Reszka
Paweł Reszka

Reputation: 1557

Change your class to this:

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

    public int CompareTo(Person other)
    {
        return Age.CompareTo(other.Age);
    }
}

If you create class with IComperable<int> you are able to compare it with int, not with the same class. You have to pass to the template the same class/struct as one you are comparing with.

Upvotes: 10

user2711965
user2711965

Reputation: 1825

You can implement Icompareable<Person> as the other answer states or you can implement IComparable like:

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

    public int CompareTo(int other)
    {
        return Age.CompareTo(other);
    }

    public int CompareTo(object obj)
    {
        Person otherPerson = obj as Person;
        if (obj == null)
            return 0;
        else
        {

            return Age.CompareTo(otherPerson.Age);
        }
    }
}

You can also use LINQ to order your List like:

foreach (Person item in list2.OrderBy(r=> r.Age))

Upvotes: 1

Omri Aharon
Omri Aharon

Reputation: 17064

You need to change your generic to Person since you are comparing Person to Person, and not Person to int:

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


        public int CompareTo(Person other)
        {
            return Age.CompareTo(other.Age);
        }
    }

Also, you do not need to cast to an Array afterwards, you can keep it as a list:

List<Person> list2 = new List<Person>();

            list2.Add(new Person() { Age = 80 });
            list2.Add(new Person() { Age = 45 });
            list2.Add(new Person() { Age = 3 });
            list2.Add(new Person() { Age = 77 });
            list2.Add(new Person() { Age = 45 });

            list2.Sort();

            foreach (Person item in list2)
            {
                Console.WriteLine(item.Age);
            }

Upvotes: 4

Related Questions