Thursday, June 11, 2009

In This World - 14

Any mistake is a big failure if we don't understand why and how it happened.

Friday, June 05, 2009

DotNet: Generic Sorting Class

Recently, I was searching for a generic sorting approach on dotnet List. Many articles (Like one, two..etc) were suggesting standard way of creating IComparer implementer class and using that with generic list (List <T>) in our application. Writing IComparer class for every business object not only take huge time also create challenges in code management when it grow considerably. So, here is simple and effective generic sorting class which can be used with any custom business object and can be sorted on any one of its properties.

All you have to do is, copy paste the complete code in to a new .cs file.

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace Srushti.Business
{
public class GenericComparer<T> : IComparer<T>
{
string _propName = string.Empty;
bool _sortDirection = true;
public GenericComparer(string propertyName, bool SortAscending)
{
_propName = propertyName;
_sortDirection = SortAscending;
}

private int CompareAsc(object o1, object o2)
{
if (o1 is IComparable)
return ((IComparable)o1).CompareTo(o2);
else if (o1.Equals(o2))
return 0;
else
return o1.ToString().CompareTo(o2);
}
#region IComparer<T> Members

public int Compare(T x, T y)
{
PropertyInfo pi = x.GetType().GetProperty(_propName);
object o1 = pi.GetValue(x, null);

pi = y.GetType().GetProperty(_propName);
object o2 = pi.GetValue(y, null);

if (_sortDirection == false)
return CompareAsc(o1, o2) * -1;
else
return CompareAsc(o1, o2);
}
#endregion
}
}


...and start consuming it as shown below. You have to supply, property name (as String) on which you want to sort the list and sorting direction (Boolean, true for ascending and false for descending) to GenericComparer() constructor.

private void Form1_Load(object sender, EventArgs e)
{
List empList = new List();
empList.Add(new Employee() { ID = 1, Name = "Three" });
empList.Add(new Employee() { ID = 2, Name = "Two" });
empList.Add(new Employee() { ID = 3, Name = "One" });

/*** Generic Comparer ***/
empList.Sort(new GenericComparer("Name", true));

foreach (Employee em in empList)
MessageBox.Show(em.ID.ToString());
}

public class Employee
{
public int ID { get; set; }
public string Name { get; set; }
}

Please Note: Class properties with complex data types like DateTime, Nullable might require special attention.