Building C# Comparable Objects: IComparable versus IComparer - Quick Recap
(Page 3 of 4 )
If we need to sort objects for classes that we create, we need to implement the IComparable interface to tell the runtime how to sort the objects. In our employee example we sorted the list of employees by id. Can we sort the employees by name instead? Sure we can. Just change the CompareTo() method to return -1, 0, or 1 based on the name comparison, not the id.
Although this change works perfectly fine, it is short of being complete. When our sorting requirements change, the CompareTo() method changes. It will be ideal if we can keep the CompareTo() method as is, but implement other interfaces that satisfy different sorting conditions. This is where the IComparer interface comes to the rescue. The IComparer interface has a Compare() method that has the following signature:
public int Compare( object obj1, object obj2)
Notice that the method still returns an integer like the CompareTo() method in the IComparable interface. The difference, however, is in the parameters. This method takes two parameters instead of one: obj1 and obj2. These are the two objects that we are comparing. We first cast them to the appropriate type, then we compare them based on our needs.
Since the Compare() method takes two objects that we are comparing as parameters, we normally do not implement the IComparer interface in the same class where we implemented the IComparable interface. Instead, we create a separate class that implements the IComparer interface and pass a new instance of that class to the Array.Sort() method. This method is overloaded to accept an IComparer interface as a parameter:
public static void Sort(Array array, IComparer comparer)
Let’s first implement the method Compare()in a class called EmployeeComparer :
class EmployeeComparer : IComparer
{
public EmployeeComparer() { }
public int Compare( object obj1, object obj2)
{
Employee e1 = ( Employee )obj1;
Employee e2 = ( Employee )obj2;
return string .Compare(e1.Name, e2.Name);
}
}
Notice how we cast the objects to Employee , then we call the Compare() method of the string class to do the actual comparison by passing the employees’ names as parameters. The only thing we have left now is to pass an instance of the EmployeeComparer class to the Sort method:
Array .Sort(employees, new EmployeeComparer ());
By doing so, the employees can now be sorted by name instead of id. We can even go a step further by defining a static property in the Employee class that returns a new EmployeeComparer casted as an IComparer :
public static IComparer SortByEmployeeName
{
get { return ( IComparer ) new EmployeeComparer(); }
}
Now the call in the Sort method is more natural:
Array .Sort(employees, Employee.SortByEmployeeName);
Next: Full Program >>
More C# Articles
More By Ayad Boudiab