views:

170

answers:

5

Hi, I've got a static method that accepts two object type variables and runs the CompareTo() method:

public static int Compare(Object objA, Object objB)
{
   return (((IComparable)objA).CompareTo(objB));
}

Problem is that CompareTo() throws an exception when trying to compare between different types (e.g. int and double). Does any one know of a better way in C#, to compare between two different types? Or a workaround to this problem?

Thanks

+2  A: 

There is no general way to solve that problem in C#, because there is no general solution for it. If there is no lose of information, C# compiler will implicitly convert one type to another and then compare them. In any other case, this will throw an exception.

In this example, the programmer who made an implementation of IComplarable interface is responsible to make a decision if two objects are comparable, and you, as a user of a class has no influence on that.

Nenad
A: 

A possible workaround is to use the IComparable<T> interface, through reflection :

public static int Compare(Object objA, Object objB)
{
    Type comparableType = typeof(IComparable<>).MakeGenericType(objA.GetType());
    MethodInfo compareMethod = comparableType.GetMethod("CompareTo");
    return (int)compareMethod.Invoke(objA, new[] { objB });
}

However, it will be slower, and will only work if the type of objB can be converted to the type of objA.

Thomas Levesque
+1  A: 

If working on numeric values only, you can provide a workaround on the issue described by Nenad by using this :

public static int Compare(Object objA, Object objB)
{
    object objB_as_AType = System.Convert.ChangeType(objB, objA.GetType());
    return (((IComparable)objA).CompareTo(objB_as_AType));
}

But be very careful because you're assuming A is IComparable without any check and you'll have to guarantee that the involved types do have conversions into each other.

Seb
A: 

If you're only comparing numbers, this will work for most cases:

public static int Compare(Object objA, Object objB) 
{ 
   return (((IComparable)Convert.ToDouble(objA)).CompareTo(Convert.ToDouble(objB))); 
} 
Gabe
A: 

You have to build your own logic to do this, mostly because only you know what the underlying comparison should do.

e.g Taking your example, comparing

int i = 10;
double d = 10.2;

are these equal? Should the integer be promoted to be a double, then compared? Then no, not equal.
Should the double be truncated to an integer? Then yes, they're equal.

In your static method, you need to check to see if the types of A & B are the same, if so, then you can call a.compareTo(b).

If not, then you need to decide how you want to compare the different types, and implement that solution in your static method.

Hope this helps

Binary Worrier