65.9K
CodeProject is changing. Read more.
Home

Sorting Generic Lists and IEnumerables by Object Property Name

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.50/5 (5 votes)

Jul 16, 2008

CPOL

2 min read

viewsIcon

35568

Easy sorting of Generic List and IEnumerable lists by property name.

Introduction

Here are a couple of really cool methods that makes it very easy to sort generic List<>s and IEnumerable collections by the collection item object property name.

Background

I was working on a project and needed to bind a generic list to a GridView control. I was dynamically binding the list, and I needed an easy way to change the list sort using only a property name. I came up with a couple of methods that makes this really easy.

The first method allows you to directly sort a generic List<> object using Reflection to pull the property, and if the property inherits the IComparable interface, then it will sort the list by that field.

The second method takes in an IEnumerable and performs the same operation, but returns a sorted List<>.

Using the Code

Here is the first method that sorts a generic List<>. You can see it takes in a List<T> as the data source, the name of the property in the object <T> that you wish to sort by, and the sort direction.

First, using Reflection, it looks to find the supplied property name in the object of type <T>. It uses this property to create a Comparison<> delegate that will be used to sort the items in the List<>. In the comparison delegate, it determines the sort direction and sets the order in which each value will be sorted in. valueA is always compared to valueB, so the sort direction determines the order in which the properties will be assigned to these two variables.

After that, the Comparison delegate is passed into the List<>.Sort() method to sort the list.

public void SortList<T>(List<T> dataSource, string fieldName, SortDirection sortDirection)
{
    PropertyInfo propInfo = typeof(T).GetProperty(fieldName);
    Comparison<T> compare = delegate(T a, T b)
    {
        bool asc = sortDirection == SortDirection.Ascending;
        object valueA = asc ? propInfo.GetValue(a, null) : propInfo.GetValue(b, null);
        object valueB = asc ? propInfo.GetValue(b, null) : propInfo.GetValue(a, null);

        return valueA is IComparable ? ((IComparable)valueA).CompareTo(valueB) : 0;
    };
    dataSource.Sort(compare);
}

The second method performs the same operation, except it places the elements of the IEnumerable into a List<>, sorts the new list, and then returns it.

private List<T> CreateSortList<T>(IEnumerable<T> dataSource, 
                string fieldName, SortDirection sortDirection)
{
    List<T> returnList = new List<T>();
    returnList.AddRange(dataSource);
    PropertyInfo propInfo = typeof(T).GetProperty(fieldName);
    Comparison compare = delegate(T a, T b)
    {
        bool asc = sortDirection == SortDirection.Ascending;
        object valueA = asc ? propInfo.GetValue(a, null) : propInfo.GetValue(b, null);
        object valueB = asc ? propInfo.GetValue(b, null) : propInfo.GetValue(a, null);

        return valueA is IComparable ? ((IComparable)valueA).CompareTo(valueB) : 0;
    };
    returnList.Sort(compare);
    return returnList;
}

History

  • Created: 7/16/2008.