Sort a ArrayList of Objects based on parameter with IComparable

260 views Asked by At

I created a small test program to gain some experience with the IComparable interface in C#. I need to use the interface for other stuff in future.

In the program I'd like to sort a ArraList of customers based on the salary. Executing my code I always receive the "System.InvalidOperationException" exception.

I already tried different versions of the code and checked a few tutorials, always with the same result.

My code:

using System;
using System.Collections;

namespace CsTest
{
    public class Program
    {
        public static void Main()
        {
            Customer customer1 = new Customer()
            {
                ID = 101,
                Name = "Ted",
                Salary = 4000
            };

            Customer customer2 = new Customer()
            {
                ID = 102,
                Name = "Tod",
                Salary = 7000
            };

            Customer customer3 = new Customer()
            {
                ID = 103,
                Name = "Tom",
                Salary = 5500
            };

            ArrayList listCustomers = new ArrayList();
            listCustomers.Add(customer1);
            listCustomers.Add(customer2);
            listCustomers.Add(customer3);

            Console.WriteLine("Customers before sorting");
            foreach (Customer customer in listCustomers)
            {
                Console.WriteLine(customer.Name + " - " + customer.Salary);
            }

            // Sort() method should sort customers by salary
            listCustomers.Sort();

            Console.WriteLine("Customers after sorting");
            foreach (Customer customer in listCustomers)
            {
                Console.WriteLine(customer.Name + " - " + customer.Salary);
            }
        }
    }

public class Customer : IComparable<Customer>
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public int Salary { get; set; }

        public int CompareTo(Customer obj)
        { 
            return this.Salary.CompareTo(obj.Salary);
        }
    }
}
2

There are 2 answers

2
Sotiris Panopoulos On BEST ANSWER

Is there a specific reason you want to use an ArrayList instead of a List<Customer>? A typed List is suggested in general, as it will only accept objects of the specified type.

The issue here is that ArrayList.Sort() does not use the IComparable interface. Check the remarks here, where it states that you have to implement the IComparer interface and use the .Sort(comparer) overload.

This is your one option. The other option (much much easier) is to use a List<Customer> and it will use your IComparable implementation out of the box. Your choice :)

1
jdweng On

Here is solution using original ArrayList

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        public static void Main()
        {
            Customer customer1 = new Customer()
            {
                ID = 101,
                Name = "Ted",
                Salary = 4000
            };

            Customer customer2 = new Customer()
            {
                ID = 102,
                Name = "Tod",
                Salary = 7000
            };

            Customer customer3 = new Customer()
            {
                ID = 103,
                Name = "Tom",
                Salary = 5500
            };

            ArrayList listCustomers = new ArrayList();
            listCustomers.Add(customer1);
            listCustomers.Add(customer2);
            listCustomers.Add(customer3);

            Console.WriteLine("Customers before sorting");
            foreach (Customer customer in listCustomers)
            {
                Console.WriteLine(customer.Name + " - " + customer.Salary);
            }

            // Sort() method should sort customers by salary

            Customer sortCustomer = new Customer();
            listCustomers.Sort(sortCustomer);

            Console.WriteLine("Customers after sorting");
            foreach (Customer customer in listCustomers)
            {
                Console.WriteLine(customer.Name + " - " + customer.Salary);
            }
        }
    }

    public class Customer : IComparer 
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public int Salary { get; set; }

          int IComparer.Compare( Object x, Object y )  {
          return( (new CaseInsensitiveComparer()).Compare( ((Customer)x).Salary, ((Customer)y).Salary) );
        }
    }
}