Click here to Skip to main content
12,955,614 members (61,080 online)
Click here to Skip to main content
Add your own
alternative version


16 bookmarked
Posted 30 Dec 2005

Generic IComparer

, 30 Dec 2005
Rate this:
Please Sign up or sign in to vote.
An article on implementing a generic comparer.

Sample Image


A great article by Ryan Beesley on this site demonstrates how to sort a collection of objects using multiple IComparer classes. This is a common way of sorting data, and you will find several articles on this subject. I will show you how to sort a collection on multiple properties, using a generic IComparer class.


Basically, implementing sort on a collection requires two actions:

  1. Creating a class which implements the IComparer interface, and manage, in the Compare method, the way objects has to be compared.
  2. Overloading the Sort method on the collection, and using the IComparer class defined on step 1.

The problem with this approach is that you have to create as much classes than there are properties to compare. Using Reflection allows you to create only one comparer class which will manage all possibilities!

Using the code

First, we will create a collection, and the multiple objects that this collection will hold. I've used the same architecture that Ryan Beesley used in his article, so you can easily compare the two techniques.

So we will have fruits (Apple, Banana, and Cantaloupe), which will have three properties: Name, Mass, and Color. All fruits will have the same interface: Fruit.

Here is the code for Fruit:

public class Fruit
    public virtual float Mass
      get { return (float.NaN); }
    public virtual string Color
      get { return (null); }
    public virtual string Name
      get { return (string.Empty ); }

Apple, Banana, and Cantaloupe derive from Fruit. Here is, for example, the code for Banana:

public class Banana : Fruit
    public override float Mass
        get { return (92.0f); }
    public override string Color
        get { return ("Yellow"); }
    public override string Name
        get { return ("Banana"); }

A collection of fruits will be implemented like this:

public FruitBasket : CollectionBase
    /// <sumary>
    /// Get or set the <see cref='Fruit'/> at the specified index
    /// </sumary>
    /// <value></value>
    public virtual Fruit this[int index]
      get { return (Fruit) List[index]; }
      set { List[index] = value; }

    /// <sumary>
    /// Add the specified Fruit  to the collection
    /// </sumary>
    /// <param name='value'>Value.</param>
    /// <returns></returns>;
    public virtual int Add(Fruit value)
        return List.Add(value);

And now, as seen in the Background section, we have to do two steps to implement sorting.

First, create a class which implements the IComparer interface. This comparer will have two properties. One which holds the property name of the object to compare, and the second to define if we want to sort objects ascending or descending. The comparer will also have a Compare method, allowing us to define how to compare objects. Here is the code for the IComparer object:

public enum SortOrderEnum

public class GenericComparer : IComparer
    private String _Property = null;
    private SortOrderEnum _SortOrder = SortOrderEnum.Ascending;
    public String SortProperty
        get { return _Property; }
        set { _Property = value; }

    public SortOrderEnum SortOrder
        get { return _SortOrder; }
        set { _SortOrder = value; }

    public int Compare(object x, object y)
        Fruit ing1;
        Fruit ing2;
        if (x is Fruit)
            ing1 = (Fruit) x;
            throw new ArgumentException("Object is not of type Fruit");

        if (y is Fruit)
            ing2 = (Fruit) y;
            throw new ArgumentException("Object is not of type Fruit");
        if (this.SortOrder.Equals(SortOrderEnum.Ascending))
            return ing1.CompareTo(ing2, this.SortProperty);
            return ing2.CompareTo(ing1, this.SortProperty);

As you can see, the comparer object calls the CompareTo method of the Fruit object to compare objects. This is where we will use Reflection to make this method generic. The CompareTo method will use the object and the property passed as arguments to get values to compare, using PropertyInfo. Here is the code of the method:

public int CompareTo(object obj, string Property)
        Type type = this.GetType();
        PropertyInfo propertie = type.GetProperty(Property);
        Type type2 = obj.GetType();
        PropertyInfo propertie2 = type2.GetProperty(Property);
        object[] index = null;
        object Obj1 = propertie.GetValue(this, index);
        object Obj2 = propertie2.GetValue(obj, index);
        IComparable Ic1 = (IComparable) Obj1;
        IComparable Ic2 = (IComparable) Obj2;

        int returnValue = Ic1.CompareTo(Ic2);
        return returnValue;
    catch (Exception Ex)
        throw new ArgumentException("CompareTo is not possible !");

The last thing to do is to implement the Sort method on the collection. This is done by adding this code to the collection:

public void Sort(String SortBy, SortOrderEnum SortOrder)
    GenericComparer comparer = new GenericComparer();
    comparer.SortProperty = SortBy;
    comparer.SortOrder = SortOrder;

You have now a fully working collection that we can sort on all properties, with no need to add code when we add a property.

Using the code:

FruitBasket FB = new FruitBasket() ;

Fruit.Banana banana = new Fruit.Banana() ;

Fruit.Apple apple = new Fruit.Apple() ;

Fruit.Cantaloupe cantaloupe = new Fruit.Cantaloupe()  ;

Sorting on name:

FB.Sort("Name",SortOrderEnum.Ascending );
foreach(Fruit fruit in FB)
    tvwDemo.Nodes.Add( " " + fruit.Name );


I haven't compared the time required for sorting on hundreds of objects, but we can assume that the generic IComparer will be slower (thanks to Reflection) than a specific IComparer. But enabling sort on any property without adding any code perhaps is worth this weakness.


  • Version 1 - 15 December 05 - Original version.


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


About the Author

Stephane Schwartz
United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

QuestionHow to Order the Elements of Class Pin
DeltaSoft8-Aug-07 21:37
memberDeltaSoft8-Aug-07 21:37 
GeneralCaching Pin
Joshua Nussbaum23-Nov-06 17:12
memberJoshua Nussbaum23-Nov-06 17:12 
QuestionHandling nulls Pin
sgartner7-Aug-06 11:02
membersgartner7-Aug-06 11:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170525.1 | Last Updated 30 Dec 2005
Article Copyright 2005 by Stephane Schwartz
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid