views:

500

answers:

4

I have a helper function, which basically calls CompareTo on two objects, but does some special corner case checking, converting, etc.

Originally I wrote the function as such:

public static bool BetterCompare(IComparable lhs, IComparable rhs, out retCode)
{
    ...
    retCode = lhs.CompareTo(rhs);
    ...
}

But the problem is that if I have a class AwesomeClass : IComparable<AwesomeClass>. In fact I have several as some older IComparable classes have gone IComparable<T>. Yet the compiler gets angry because it can't convert these new objects to IComparable. I don't know if this makes it worse, but some of them are abstract (though the abstract class does provide an implementation).

How can I convey "I want two objects that I can call CompareTo on" and not have the compiler give me any lip. Preferably, the new function should NOT look like BetterCompare<AwesomeClass>(this, that, out retCode);, but just "do the right thing". Or is there a better way to do this without touching every class making them both IComparable and IComparable<T>?

+9  A: 

You can either make AwesomeClass implement the nongeneric IComparable interface as well as IComparable<T>, or you can write a generic BetterCompare method:

public static bool BetterCompare<T>(T lhs, T rhs, out retCode)
    where T : IComparable<T>
{
    ...
    retCode = lhs.CompareTo(rhs);
    ...
}

(Note that this can live alongside your existing method.)

Jon Skeet
Thanks. I tried using Generics to solve the problem, but I didn't remember to qualify(?) T.
MighMoS
Congrats on 75 K
rahul
Not *really* there just yet - 74951 at the moment :)
Jon Skeet
A: 

You could always change the variables to an object type and then use reflection to see if they implement one of the interfaces and then cast them to the correct interface.

NOTE: Reflection is crazy slow, so use it with caution.

Correl
A: 

You could have a look at Comparer<T>, that implements both IComparer<T> and IComparer, and use that in the appropriate places. It may require some refactoring of your code though.

thecoop
A: 

The documentation says:

The object returned by the Default property uses the System.Collections.Generic.IComparable<T> generic interface to compare two objects. If type T does not implement the IComparable<T> generic interface, the Default property returns a Comparer<T> that uses the System.Collections.IComparable interface.

John Saunders