1

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

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
Shakti Prakash Singh
  • 2,414
  • 5
  • 35
  • 59

3 Answers3

0

If the Type is a custom class, then your custom class needs to be IComparable.

e.g.

List<FooClass>, then FooClass needs to inherit/implement IComparable.

twilson
  • 2,062
  • 14
  • 19
  • Thanks. But all the classes T can not not implement IComparable as some classes like BitmapImage, CustomCommands(implementing UICommand and has a member as BindingProperty>) are not compatible. I am not sure what to do. – Shakti Prakash Singh Feb 11 '12 at 13:50
0

You can use a generic constraint to require that T implements IComparable<T>. You can then compare two BindingProperty<T> instance by comparing their Value members. It is not clear to me if you need your class to implement IComparable or IComparable<T> but implemeting both is not much extra work.

class BindingProperty<T>
  : IComparable<BindingProperty<T>>, IComparable where T : IComparable<T> {

  public T Value { get; set; }

  public Int32 CompareTo(BindingProperty<T> other) {
    return Value.CompareTo(other.Value);
  }

  public Int32 CompareTo(Object other) {
    if (other == null)
      return 1;
    var otherBindingProperty = other as BindingProperty<T>;
    if (otherBindingProperty == null)
      throw new ArgumentException();
    return CompareTo(otherBindingProperty);
  }

}
Martin Liversage
  • 104,481
  • 22
  • 209
  • 256
  • When I implement the above solution, I get an error message _"Error:The type 'System.Windows.Media.Imaging.BitmapImage' cannot be used as type parameter 'T' in the generic type or method 'Bally.UI.Framework.BindingProperty'. There is no implicit reference conversion from 'System.Windows.Media.Imaging.BitmapImage' to 'System.IComparable'_." This is from another part of the project. The BindingProperty is being used as **BindingProperty**. Is there a way out? – Shakti Prakash Singh Feb 11 '12 at 13:43
0

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>");
        }
    }
Magnus
  • 45,362
  • 8
  • 80
  • 118
  • When I implement the above solution, I get an error message _"Error:The type 'System.Windows.Media.Imaging.BitmapImage' cannot be used as type parameter 'T' in the generic type or method 'Bally.UI.Framework.BindingProperty'. There is no implicit reference conversion from 'System.Windows.Media.Imaging.BitmapImage' to 'System.IComparable'_." This is from another part of the project. The BindingProperty is being used as **BindingProperty**. Is there a way out? – Shakti Prakash Singh Feb 11 '12 at 13:48
  • 1
    The generic type must implement `IComparable` or you wont be able to sort on it. `BitmapImage` does not. And it does not make much sense to sort on a image. – Magnus Feb 11 '12 at 13:50
  • I understand as to implementing IComparable is essential, but the other part of the code, (which is as part of the existing Framework), does have this BitmapImage as BindingProperty as a type. – Shakti Prakash Singh Feb 13 '12 at 17:30