first_page the funky knowledge base
personal notes from way, _way_ back and maybe today

“Sorting Lists using IComparable and IComparer Interface in .NET”

It's easy to sort a list of strings or integers by just calling the List.Sort() method, but how can we sort two objects and based on what field?

Let's implement IComparable<> interface to our Employee class:

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

 #region IComparable&lt;Employee&gt; Members
   
 public int CompareTo( Employee other )
 {
     if ( this.Salary &lt; other.Salary ) return 1;
     else if ( this.Salary &gt; other.Salary ) return -1;
     else return 0;
 }
    
 #endregion

}

In the above code, we are sorting objects based on salary of employee in descending order, by implementing CompareTo() method of IComparable interface which takes Employee reference as a parameter. Now, calling empList.Sort() gives no exception and empList is well sorted by salary.

But sometimes, we may need to sort a list of objects when class does not implement IComparable<> interface and also we may need various kinds of sorting on that class like:

  1. Sort Employees by Salary in Ascending Order
  2. Sort Employees by Salary in Descending Order
  3. Sort Employees by Name

To solve this problem, .NET provides a special interface called IComparer<> which has a method Compare(), takes two object parameters X, Y and returns an int. Use of IComparer<> interface tells List how exactly you want to sort.

class Employee_SortBySalaryByAscendingOrder : IComparer<Employee> { #region IComparer<Employee> Members

public int Compare( Employee x, Employee y )
{
    if ( x.Salary &gt; y.Salary ) return 1;
    else if ( x.Salary &lt; y.Salary ) return -1;
    else return 0;
}

#endregion

}

class Employee_SortBySalaryByDescendingOrder : IComparer<Employee> { #region IComparer<Employee> Members

public int Compare( Employee x, Employee y )
{
    if ( x.Salary &lt; y.Salary ) return 1;
    else if ( x.Salary &gt; y.Salary ) return -1;
    else return 0;
}

#endregion

}

class Employee_SortByName : IComparer<Employee> { #region IComparer<Employee> Members

public int Compare( Employee x, Employee y )
{
    return string.Compare( x.Name, y.Name );
}

#endregion

}

The above code introduces three classes by implementing Compare() method of IComparer interface.

Now, how do we use this? We just have to pass the reference of these classes as a object parameter to Sort() method as shown below:

// Use Collection Initializers( C# 3.0 ) to initialize the List List<Employee> empList = new List<Employee>() { new Employee { Name = "a", Salary = 14000 }, new Employee { Name = "b", Salary = 13000 } };

Employee_SortBySalaryByAscendingOrder eAsc = new Employee_SortBySalaryByAscendingOrder(); // Sort Employees by salary by ascending order.
empList.Sort( eAsc );

Employee_SortBySalaryByDescendingOrder eDsc = new Employee_SortBySalaryByDescendingOrder(); // Sort Employees by salary by descending order. empList.Sort( eDsc );

Employee_SortByName eName = new Employee_SortByName(); // Sort Employees by their names.
empList.Sort( eName );

Conclusion

Sorting Lists is simple as long as you sort basic elements like strings and integers for which comparison classes are defined.

Usage of IComparable<> and IComparer<> interface helps to sort Lists of objects on custom classes easily.

[http://www.codeproject.com/KB/cs/Sorting_Lists.aspx?display=Print]

mod date: 2009-10-06T16:01:11.000Z