DRY! GenericComparer<TType> for sorting Generic Lists

I’m a pretty firm believer in the Ruby/Ruby on Rails idea of DRY (“Don’t Repeat Yourself”).

That said, I get pretty tired of writing comparers for sorting lists and generic lists. Every one of these comparers is exactly the same: you specify a list of properties related to the object and a sort direction, then call compare on those properties.

This can be changed with a little reflection:

public class GenericComparer<T> : IComparer<T>
    {
        public string SortExpression { get; set; }
        public int SortDirection { get; set; } // 0:Ascending, 1:Descending

        public GenericComparer(string sortExpression, int sortDirection)
        {
            this.SortExpression = sortExpression;
            this.SortDirection = sortDirection; 
        }
        public GenericComparer() { }

        #region IComparer<T> Members
        public int Compare(T x, T y)
        {
            PropertyInfo propertyInfo = typeof(T).GetProperty(SortExpression);
            IComparable obj1 = (IComparable)propertyInfo.GetValue(x, null);
            IComparable obj2 = (IComparable)propertyInfo.GetValue(y, null);

            if (SortDirection == 0)
            {
                return obj1.CompareTo(obj2);
            }
            else return obj2.CompareTo(obj1); 
        }
        #endregion
    }

This is a code snippet I love to have in my arsenal.

Here’s how you use it:

List<MyObject> objectList = GetObjects(); /* from your repository or whatever */
objectList.Sort(new GenericComparer<MyObject>("ObjectPropertyName", (int)SortDirection.Descending));
dropdown.DataSource = objectList;
dropdown.DataBind();

Note that Sort returns void. This means you can’t throw this to the right of a DataSource call. You’d have to call this, then call your DataSource/DataBind.

Related Articles