Search code examples
.netgenericscomparetoicomparable

Implementing Icomparable Interface for generic class


I am not able to find out as to how to implement the IComparable interface method CompareTo for a generic class.

I have a class called BindingProperty<T> which is used to create a List<BindingProperty<intOrString>> to bind to a DataGrid. The problem is that the I can not perform the Sort operation as the IComparable interface is not implemented by this BindingProperty<T> class. The result of comparison would depend on a data member 'Value' of the the BindingProperty<T> class where 'Value' is of Type T. When I click on the column header of the DataGrid, I get an exception that CompareTo() method is not implemented.

I would need help to implement this interface. Should I be using IComparable<T>? If yes, how do I do it?

Thanks in advance Shakti


Solution

  • Set up a generic type constraint on T.

    public class BindingProperty<T> : IComparable where T : IComparable
    {
        public T Value {get; set;}
    
        public int CompareTo(object obj)
        {
           if (obj == null) return 1;
    
           var other = obj as BindingProperty<T>;
           if (other != null) 
                return Value.CompareTo(other.Value);
           else
                throw new ArgumentException("Object is not a BindingProperty<T>");
        }
    }
    

    Edit:
    Alternative solution to handle if value does not implement IComparable. This will support all types, just wont sort if they do not implement IComparable.

    public class BindingProperty<T> : IComparable
        {
            public T Value {get; set;}
    
            public int CompareTo(object obj)
            {
               if (obj == null) return 1;
    
               var other = obj as BindingProperty<T>;
               if (other != null) 
               {
                   var other2 = other as IComparable;
                   if(other2 != null)
                      return other2.CompareTo(Value);
                   else
                      return 1; //Does not implement IComparable, always return 1
               }
               else
                    throw new ArgumentException("Object is not a BindingProperty<T>");
            }
        }