About 3 months ago I had a need to do some in-memory sorting on a generic list of objects which were being bound to a GridView control. Due to the fact that we were not working with standard ADO.NET objects and that LINQ has not been fully released, we decided to get clever and come up with a simple sorting method which could handle the case where the a list of objects could be sorted by any one of the fields which was clicked on the GridView control. Note: For the sake of simplicity, I created a dumbed down version of both the object and the sorting method, such that all properties were strings.
For weeks I had heard Sasha talk about how neat anonymous methods were in .NET 2.0, so we sat down and wrote out this nice little SortBy() function. 1st we enumerated through the generic list. 2nd we took the passed propertyname and did a compare between the properties in the two different customer objects. 3rd we used the SortDirection to determine how we would return the compare results. The result, a great little method which is capable of sorting a generic collection with only the objects propertyname and the sortdirection supplied.
public class CustomerList : List<Customer>
{
/// <summary>
/// Sorts the CustomerList using Generics, Anonymous Methods, and Reflection
/// </summary>
/// <param name="propertyName">Property Name to sort the List with</param>
/// <param name="sortDirection">Direction to sort the List</param>
public void SortBy(string propertyName, SortDirection sortDirection)
{
this.Sort
(
//Anonymous method used sort the base generic list.
delegate(Customer item1, Customer item2)
{
//Use reflection to get the Properties
PropertyInfo prop1 = item1.GetType().GetProperty(propertyName);
PropertyInfo prop2 = item2.GetType().GetProperty(propertyName);
if (prop1 == null || prop2 == null)
{
throw new ArgumentException("Invalid property name: " +
propertyName + " specified.");
}
//Get the property values from each of the objects
string value1 = (string)prop1.GetValue(item1, null);
string value2 = (string)prop2.GetValue(item2, null);
int compareVal = Comparer.Default.Compare(value1, value2);
if (sortDirection == SortDirection.Ascending)
return compareVal;
else
return compareVal * -1; //return the negated value
}
);
}
}
public class Customer
{
private string _id;
private string _firstName;
private string _lastName;
private string _age;
public string ID
{
get { return _id; }
set { _id = value; }
}
public string FirstName
{
get { return _firstName; }
set { _firstName = value; }
}
public string LastName
{
get { return _lastName; }
set { _lastName = value; }
}
public string Age
{
get { return _age; }
set { _age = value; }
}
}