Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Sort generic collection

0.00/5 (No votes)
9 Apr 2008 1  
This article describe how to sort generic collections

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)
            'find if we want to sort asc or desc
            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
            'get the properties of the objects
            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

            'find the column we want to sort based on
            For i As Integer = 0 To propsx.Length - 1
                If _sortColumn.ToLower() = propsx(i).Name.ToLower() Then
                    'find the type of column so we know how to sort
                    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).

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here