Yossin
Yossin

Reputation: 11

Using CompareTo() on different .NET types (e.g. int vs. double)

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

Upvotes: 1

Views: 2297

Answers (5)

Binary Worrier
Binary Worrier

Reputation: 51711

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

Upvotes: 1

Gabe
Gabe

Reputation: 86718

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))); 
} 

Upvotes: 0

Seb
Seb

Reputation: 2715

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.

Upvotes: 1

Thomas Levesque
Thomas Levesque

Reputation: 292435

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.

Upvotes: 1

Nenad Dobrilovic
Nenad Dobrilovic

Reputation: 1555

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.

Upvotes: 2

Related Questions