Generics and Implementing IComparable

CSharpened picture CSharpened · Feb 1, 2012 · Viewed 13.7k times · Source

I am very new to generics and I am trying to write a simple class which will be generic but also allow sorting of some description on a string member variable.

At the moment I have a basic class but when I try to implement the interface member CompareTo() I get an error at the top telling me it is not implemented. What is the issue here?

using System;

namespace GenericsPracticeConsole.Types
{
    class SortableGenericType<T> : IComparable
    {
        private T t;
        private string stringName;

        public T name
        {
            get { return t; }
            set { t = value; }
        }

        public int CompareTo(SortableGenericType<T> ourObject)
        {
            return stringName.CompareTo(ourObject.stringName);
        }
    }
}

Answer

Ali Ferhat picture Ali Ferhat · Feb 1, 2012

There are two interfaces IComparable and IComparable<U>. IComparable is the older one (that came before generics) which requires instances to be compared with arbitrary objects. IComparable<U> requires instances to be compared with instances of U. If you want to declare that you will compare instances of SortableGenericType on stringName fields this is what you should do:

class SortableGenericType<T> : IComparable<SortableGenericType<T>>
{
   //
}

If you also want to implement IComparable:

   class SortableGenericType<T> : IComparable, IComparable<SortableGenericType<T>> 
   {
      private string stringName;
      public T name { get; set; }

      public int CompareTo(SortableGenericType<T> ourObject)
      {
         //I forgot to add this statement:
         if(ourObject == null) 
             return -1; 
         return stringName.CompareTo(ourObject.stringName);
      }

      public int CompareTo(object obj)
      {
         if (obj.GetType() != GetType())
            return -1;
         return CompareTo(obj as SortableGenericType<T>);
      }
   }

If your class was a collection that is going to hold items of type T and you needed those items to be orderable (this is not what you ask but it is the most common scenario) than you would require T to be IComparable<T> :

   class SomeCollection<T> where T : IComparable<T>
   {
      private List<T> items; 

      private void Sort()
      {
         //
         T item1;
         T item2;
         if(item1.CompareTo(item2) < 0)
         {
            //bla bla
         }
      }
   }