A generic sorter for strongly-typed collections

Late last night I was doing some development work on a website for our investment club. I had a strongly-typed collection of "Stock" objects, and wanted to be able to sort them on any parameter (StockName, SharePrice, Volume, MarketCap, etc..) in either descending or ascending order. I didn't want to have to write a separate comparer for each property. Reflection to the rescue! Below is a GenericSorter class, the use of which allows for the development of a Sort() method on the collection taking as a parameter the name of the property on which to sort.  Smart.

using System;
using System.Collections;
using System.Globalization;
using System.Reflection;
namespace IanNelson.Utilities
{
/// <SUMMARY>
/// A generic sorter, inheriting from IComparer,
/// intended to allow for the sorting of
/// strongly-typed collections on any named public property
/// which implements IComparable
/// </SUMMARY>
public class GenericSorter : IComparer
{
string sortPropertyName;
SortOrder sortOrder;
public GenericSorter(string sortPropertyName)
{
this.sortPropertyName=sortPropertyName;
this.sortDirection=SortDirection.Ascending;
// default to ascending order

}
public GenericSorter(string sortPropertyName,
SortDirection sortOrder)
{
this.sortPropertyName=sortPropertyName;
this.sortDirection=sortDirection;
}
public int Compare(object x, object y)
{
// Get the values of the relevant property on the
// x and y objects

object valueOfX = x.GetType().
GetProperty(sortPropertyName).GetValue(x,null);
object valueOfY = y.GetType().
GetProperty(sortPropertyName).GetValue(y,null);
// Do the comparison
if (sortOrder==SortOrder.Ascending)
{
return ((IComparable)valueOfX).CompareTo(valueOfY);
}
else

{
return ((IComparable)valueOfY).CompareTo(valueOfX);
}
}
}
///
/// Enumerator to indicate whether to sort in ascending or
/// descending order
///
public enum SortDirection
{
Ascending,
Descending
}
}

To use this class, within a collection which inherits from System.Collections.CollectionBase, we just need to expose a Sort() method along the lines of:

public void Sort(string sortPropertyName, 
SortDirection sortDirection)
{
InnerList.Sort(new IanNelson.Utilities.GenericSorter(
sortPropertyName,sortDirection));
}

Bob's your uncle.

Update [2006-02-27]: The above class is no match for some much more fully-featured code that was anonymously sent to me earlier this month which allows for sorting on multiple properties to arbitrary depth within the domain object model, using a simple SQL-like syntax.  Check it out...

#1 rob on 25 Jul 2005 at 22:40

this is really cool. thanks ian.

#2 Clancy on 30 Aug 2005 at 16:30

Great Googley-moogeley - it works!



The objects I am using are bindable, so sorting using this method for a web based datagrid is REALLY handy!


Leave a Comment