Click here to Skip to main content
15,895,656 members
Articles / Programming Languages / C#

Sorting Collection of Custom Types Generically

Rate me:
Please Sign up or sign in to vote.
2.91/5 (10 votes)
28 Jul 2007CPOL1 min read 34.6K   136   12  
Sorting a collection of custom types
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace Sort
{
    class Program
    {
        public enum Direction
        {
            Ascending = 0,
            Descending = 1,
        }

        static void Main(string[] args)
        {
            List<Entity> entities = new List<Entity>();
            entities.Add(new Entity("tommy", 10, 99));
            entities.Add(new Entity("Dicky", 12, 100));
            entities.Add(new Entity("Harry", 11, 90));
            
            List<string> collString = new List<string>();
            collString.Add("tommy");
            collString.Add("Dicky");
            collString.Add("Harry");

            Console.WriteLine("------------------------sorting using .NET supplied List Sort----------------------------------------------");
            Console.WriteLine();
            //entities.Sort(); will not work, type entity should implement IComparable and give logic regarding comparison of two entity types
            collString.Sort(); //Works fine for basic types implement IComparable.
            

            Console.WriteLine("------------------------sort on " + typeof(Entity).GetProperties()[2].Name + " ascending ----------------------------------");
            Console.WriteLine();
            entities.Sort(new CompareEntities<Entity>(Direction.Ascending, typeof(Entity).GetProperties()[2].Name));

            PrintEntities(entities);

            Console.WriteLine("-------------------------sort on " + typeof(Entity).GetProperties()[1].Name + " ascending----------------------------------");
            Console.WriteLine();
            entities.Sort(new CompareEntities<Entity>(Direction.Ascending, typeof(Entity).GetProperties()[1].Name));

            PrintEntities(entities);

            Console.WriteLine("--------------------------sort on " + typeof(Entity).GetProperties()[4].Name + " Descending---------------------------------");
            Console.WriteLine();
            entities.Sort(new CompareEntities<Entity>(Direction.Descending, typeof(Entity).GetProperties()[4].Name));

            PrintEntities(entities);

            Console.WriteLine("--------------------------sort on field 3 ascending-------------------------------------------------------");
            Console.WriteLine();
            entities.Sort(new CompareEntitiesByPropertyIndex<Entity>(Direction.Ascending, 3));

            PrintEntities(entities);

            Console.WriteLine();
            Console.WriteLine("Press any key......");

            Console.Read();

        }

        public static void PrintEntities(List<Entity> entities)
        {
            foreach (Entity entity in entities)
                Console.WriteLine(String.Format("Name : {0} RollNumber : {1} Total : {2} CreatedOn : {3}", 
                    entity.Name, entity.RollNumber.ToString(), entity.Total.ToString(), entity.CreatedOn.ToString()));
        }

        public class CompareEntities<T> : IComparer<T>
        {
            private Direction _sortDirection;
            public Direction SortDirection
            {
                get { return _sortDirection; }
                set { _sortDirection = value; }
            }

            private string _propertyName;
            public string PropertyName
            {
                get { return _propertyName; }
                set { _propertyName = value; }
            }

            public CompareEntities(
                Direction dir, string fieldName)
            {
                SortDirection = dir;
                PropertyName = fieldName;
            }

            #region IComparer<T> Members

            public int Compare(T x, T y)
            {
                if (typeof(T).GetProperty(PropertyName) == null)
                    throw new Exception(String.Format("Given property is not part of the type {0}", PropertyName));

                object objX = typeof(T).GetProperty(PropertyName).GetValue(x, null);
                object objY = typeof(T).GetProperty(PropertyName).GetValue(y, null);

                int retVal = default(int);
                retVal = ((IComparable)objX).CompareTo((IComparable)objY);

                return retVal;
            }

            #endregion
        }

        public class CompareEntitiesByPropertyIndex<T> : IComparer<T>
        {
            CompareEntities<T> _comparer = null;
            public CompareEntitiesByPropertyIndex(
                Direction dir, int index)
            {
                _comparer = new CompareEntities<T>(dir, 
                    typeof(T).GetProperties()[index].Name);
            }

            #region IComparer<T> Members
            public int Compare(T x, T y)
            {
                return _comparer.Compare(x, y);
            }
            #endregion
        }

        public class BaseEntity
        {
            private DateTime _createdOn;
            public DateTime CreatedOn
            {
                get { return _createdOn; }
                set { _createdOn = value; }
            }

            private DateTime _updatedOn;
            public DateTime UpdatedOn
            {
                get { return _updatedOn; }
                set { _updatedOn = value; }
            }
        }

        public class Entity : BaseEntity 
        {
            private string _name;
            public string Name
            {
                get { return _name; }
                set { _name = value; }
            }

            private int _rollNumber;
            public int RollNumber
            {
                get { return _rollNumber; }
                set { _rollNumber = value; }
            }

            private double _total;
            public double Total
            {
                get { return _total; }
                set { _total = value; }
            }

            public Entity(string name, int rollNo, double tot)
            {
                Name = name;
                RollNumber = rollNo;
                Total = tot;
                CreatedOn = DateTime.Now.AddDays(-1);
                UpdatedOn = DateTime.Now.AddDays(1);
            }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions