Introduction
In this article I will talk about how to sort the generic collection using reflections. This is code needs to be modify if you are using a types that are not exist in the code. Also if you want to sort on some variable which its type in not one of the basic types(integer,string,..) you need to modify the code. This code just gives you a basic understanding of how to sort the collections but you need to modify it to meet your needs.
Background
One of the great benefits of the .NET 2.0 was collectiona and generics. Know we can bind a list of object to grid,dropdownlist and many more. In dataset world we can use sort method on datatable or dataview to sort the result. The same option is available on the collections. This article will discuss how to do the generic collection sorting.
Using the code
The code below shows the generic collection sorter:
Imports System.Reflection
Namespace CollectionSorter
Public Class CollectionSorter(Of T)
Implements IComparer(Of T)
#Region "Private Variables"
Private _sortColumn As String
Private _reverse As Boolean
#End Region
#Region "Constructor"
Public Sub New(ByVal sortEx As String)
If Not String.IsNullOrEmpty(sortEx) Then
_reverse = sortEx.ToLowerInvariant().EndsWith(" desc")
If _reverse Then
_sortColumn = sortEx.Substring(0, sortEx.Length - 5)
Else
If sortEx.ToLowerInvariant().EndsWith(" asc") Then
_sortColumn = sortEx.Substring(0, sortEx.Length - 4)
Else
_sortColumn = sortEx
End If
End If
End If
End Sub
#End Region
#Region "Interface Implementation"
Public Function Compare(ByVal x As T,
ByVal y As T) As Integer Implements System.Collections.Generic.IComparer(
Of T).Compare
Dim propsx() As PropertyInfo = x.GetType().GetProperties(
System.Reflection.BindingFlags.Instance Or System.Reflection.BindingFlags.Public)
Dim propsy() As PropertyInfo = x.GetType().GetProperties(
System.Reflection.BindingFlags.Instance Or System.Reflection.BindingFlags.Public)
Dim retval As Integer
For i As Integer = 0 To propsx.Length - 1
If _sortColumn.ToLower() = propsx(i).Name.ToLower() Then
Select Case propsx(i).PropertyType.Name
Case "String"
retval = CStr(propsx(i).GetValue(x, Nothing)).CompareTo(
CStr(propsy(i).GetValue(y, Nothing)))
Case "Integer"
retval = CInt(propsx(i).GetValue(x, Nothing)).CompareTo(
CInt(propsy(i).GetValue(y, Nothing)))
Case "Int32"
retval = CInt(propsx(i).GetValue(x, Nothing)).CompareTo(
CInt(propsy(i).GetValue(y, Nothing)))
Case "Int16"
retval = CInt(propsx(i).GetValue(x, Nothing)).CompareTo(
CInt(propsy(i).GetValue(y, Nothing)))
Case "DateTime"
retval = CDate(propsx(i).GetValue(x, Nothing)).CompareTo(
CDate(propsy(i).GetValue(y, Nothing)))
End Select
End If
Next
If _reverse Then
Return -1 * retval
Else
Return retval
End If
End Function
#End Region
#Region "Equal Function"
Public Function Equals(ByVal x As T, ByVal y As T) As Boolean
Dim propsx() As PropertyInfo = x.GetType().GetProperties(
System.Reflection.BindingFlags.Instance Or System.Reflection.BindingFlags.Public)
Dim propsy() As PropertyInfo = y.GetType().GetProperties(
System.Reflection.BindingFlags.Instance Or System.Reflection.BindingFlags.Public)
Dim retval As Boolean
For i As Integer = 0 To propsx.Length - 1
If _sortColumn.ToLower() = propsx(i).Name.ToLower() Then
retval = propsx(i).GetValue(x, Nothing).Equals(propsy(i).GetValue(y,
Nothing))
End If
Next
Return retval
End Function
#End Region
End Class
End Namespace
In the begining the class should inherit from IComparer(Of T)
interface. This interface has just one method. The method that needs to be implemented is:
Public Function Compare(ByVal x As T, ByVal y As T) As Integer
basically this method compare the two object of typeT
. Let 's backup alittle bit, in the constructor of this class we will get the sort expression for exmple if we have an object like book which has a property called "Title" and we want to sort based on the tilte we should use expression like "Title asc" or "Title desc". In the compare
function we will use reflector to find the column that we want to sort and the I used reflector to get the type of the column and then I used the compare method of that type to compare the values.
The other function that I implemented is Equal
.
Code below shows how to use the generic collection sorter:
Dim BookList As List(Of Book) = New List(Of Book)
Dim m_book As Book
m_book = New Book()
m_book.Author = "Bill Gates"
m_book.Title = "How to get rich as software engineer!"
m_book.PublishDate = "1/1/2000"
BookList.Add(m_book)
m_book = New Book()
m_book.Author = "Steve Job"
m_book.Title = "Why apple went down the drain!"
m_book.PublishDate = "1/1/2007"
BookList.Add(m_book)
Dim colsorter As CollectionSorter(Of Book) = New CollectionSorter(Of Book)(
"Author asc")
BookList.Sort(colsorter)
Points of Interest
To improve this code you can give the user ability to sort based on the multiple columns(properties).