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<Employee> Members
public int CompareTo( Employee other )
{
if ( this.Salary < other.Salary ) return 1;
else if ( this.Salary > 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:
- Sort Employees by Salary in Ascending Order
- Sort Employees by Salary in Descending Order
- 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 > y.Salary ) return 1;
else if ( x.Salary < 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 < y.Salary ) return 1;
else if ( x.Salary > 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]