user3186277
user3186277

Reputation: 61

iComparable Interface Workings

I have created a Customer class with iComparable Interface.

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

    public int CompareTo(Customer obj)
    {
      if (this.Salary > obj.Salary)
          return 1;
        else if
            (this.Salary < obj.Salary)
            return -1;
        else
            return 0;
     }

}

In the main program I have created a List of customers and added three customers.

List<Customer> ListCust = new List<Customer>(); 
ListCust.Add(Cust1);
ListCust.Add(Cust2);
ListCust.Add(Cust3);

I then sort the list.

ListCust.Sort();

My question is how is this sort method of list picking up the "CompareTo" part of the Customer class. Initially when I had tried to sort it without the iComparable interface it was giving me invalid operation error.

The following question is why cant I just make a "CompareTo" method in the customer class without iComparable interface and make it work?

Upvotes: 1

Views: 176

Answers (3)

Sweeper
Sweeper

Reputation: 273565

The Sort method checks whether the type parameter implements IComparable. If it does, the method casts each item in the list to IComparable. Something like this: (Might not be how they actually did it, but you get the idea.)

foreach (T item in this) {
    if (item is IComparable) {
        var castedItem = (IComparable)item;
        // do other things with castedItem
    } else {
        throw new InvalidOperationException("Sorting is not supported");
    }
}

So if you don't implement IComparable, item is IComparable evaluates to false so that's why an InvalidOperationException is thrown.

Thus, the ultimate reason is...

The source code doesn't check whether you have a CompareTo method or not. It just checks whether you have the interface implemented.

Upvotes: 2

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726987

The reason .NET could not "just" sort your Customer objects is because it has no way of guessing in what way you want to sort them: by salary, by first name, by last name, by the time they placed their first order, etc.

However, you can make it work without implementing IComparable in three different ways:

  • Pass a separate IComparer<Customer> implementation - this lets you move comparison logic to a separate class, and apply different comparison logics based on a situation.
  • Pass a Comparison<Customer> delegate - same as above, but now you don't need a separate class; this lets you provide comparison logic in a lambda.
  • Use LINQ's OrderBy instead - Similar to above, but gives you additional capabilities (filtering, projecting, grouping, etc.)

Upvotes: 2

Peter Szekeli
Peter Szekeli

Reputation: 2800

Check the documentation on MSDN of the Sort method, it says

InvalidOperationException is thrown when comparer is null, and the default comparer Comparer.Default cannot find implementation of the IComparable generic interface or the IComparable interface for type T.

It was designed this way.

Upvotes: 0

Related Questions