Stop writing IComparer classes to sort your custom collections! This article discusses sorting of a user defined collection object based on any of the properties of the business entity. This sorting technique is generic for all the collection objects. You can sort your collection based on their properties.
Solution
How it works?
SortableCollectionBase class uses "GenericComparer" class for sorting. "GenericComparer" class implements IComparer interface and compares the objects based on the public property (Sort Column) of the class type dynamically irrespective of the collection.
GenericComparer class///
/// This class is used to compare any
/// type(property) of a class.
/// This class automatically fetches the
/// type of the property and compares.
///
public sealed class GenericComparer:IGenericComparer
{
///
/// Sorting order
///
public enum SortOrder
{
Ascending = 0,
Descending = 1
}
Type objectType;
///
/// Type of the object to be compared.
///
public Type ObjectType
{
get{return objectType;}set{objectType = value;}
}
string sortcolumn = "";
///
/// Column(public property of the class) to be sorted.
///
public string SortColumn
{
get{return sortcolumn;}set{sortcolumn = value;}
}
int sortingOrder = 0;
///
/// Sorting order.
///
public int SortingOrder
{
get{return sortingOrder;}set{sortingOrder = value;}
}
///
/// Compare interface implementation
///
/// Object 1
/// Object 2
///
public int Compare(object x, object y)
{
//Dynamically get the protery info
//based on the protery name
PropertyInfo propertyInfo =
ObjectType.GetProperty(sortcolumn);
//Get the value of the instance
IComparable obj1 =
(IComparable)propertyInfo.GetValue(x,null) ;
IComparable obj2 =
(IComparable)propertyInfo.GetValue(y,null) ;
//Compare based on the sorting order.
if(sortingOrder == 0)
return ( obj1.CompareTo(obj2) );
else
return ( obj2.CompareTo(obj1) );
}
}
SortableCollectionBase class
///
/// Abstract implementation of Sortable collection.
///
public abstract class SortableCollectionBase :
CollectionBase,ISortable
{
string sortcolumn="";
public string SortColumn
{
get{return sortcolumn;}
set{sortcolumn = value;}
}
GenericComparer.SortOrder sortingOrder =
GenericComparer.SortOrder.Ascending;
public GenericComparer.SortOrder SortingOrder
{
get{return sortingOrder;}set{sortingOrder = value;}
}
Type sortObjectType;
public Type SortObjectType
{
get{return sortObjectType;} set{sortObjectType = value;}
}
public virtual void Sort()
{
if(sortcolumn == "")
throw new Exception("Sort column required.");
if(SortObjectType == null)
throw new Exception("Sort object type required.");
IGenericComparer sorter = new GenericComparer();
sorter.ObjectType = sortObjectType;
sorter.SortColumn = sortcolumn;
sorter.SortingOrder = (int)sortingOrder;
InnerList.Sort(sorter);
}
}
How to use SortableCollectionBase class?
Using SortableCollectionBase is simple and effortless. Just inherit your custom collection class from SortableCollectionBase class and in the constructor set the SortableObjectType property. Now your class becomes sortable.
For example///
/// Note : This student collection
/// inherhits SortableCollectionBase
/// In the constructor set the
/// SortObjectType for sorting.
///
public class StudentCollection :
SortableCollectionBase
{
public StudentCollection()
{
//In your collection class
//constructor add this line.
//set the SortObjectType for sorting.
base.SortObjectType = typeof(Student);
}
public Student this[ int index ]
{
get
{
return( (Student) List[index] );
}
set
{
List[index] = value;
}
}
public int Add( Student value )
{
return( List.Add( value ) );
}
public int IndexOf( Student value )
{
return( List.IndexOf( value ) );
}
public void Insert( int index, Student value )
{
List.Insert( index, value );
}
//......
}
How to sort?
To sort your custom collection call the "Sort()" method. Note: Make sure that you have set the "SortColumn" property before calling the "Sort()" method. "SortColumn" is the property of the business entity based on which the collection will be sorted. In this case SortColumn can be "name", "id" or "Dob".StudentCollection Students = new StudentCollection();
Students.Add(new Student("Sai",5,new DateTime(1914,10,4)));
Students.Add(new Student("Sree",1,new DateTime(1980,10,4)));
Students.Add(new Student("Sow",3,new DateTime(2000,4,1)));
Students.Add(new Student("Zaheer",2,new DateTime(1978,1,27)));
Students.SortColumn = "Name";
Students.SortingOrder =
GenericComparer.SortOrder.Ascending;
Students.Sort();
dataGrid1.DataSource = Students;