Reputation: 1286
I have two object
instances which could be integers or doubles. I want to find out which is the smaller:
int ix = 1;
int iy = 2;
object ox = ix;
object oy = iy;
if (ox < oy) // This is an error
{
...
}
Is it possible to perform this comparison without hideously inefficient-looking
if (ox.GetType() == typeof(int))
{
}
else if (ox.GetType() == typeof(double))
{
}
tests?
Upvotes: 0
Views: 89
Reputation: 391396
If you "know" that the types can be compared, but:
Then the way to do this is by using dynamic
:
void Main()
{
int ix = 1;
int iy = 2;
dynamic ox = ix;
dynamic oy = iy;
if (ox < oy)
Debug.WriteLine("ox < oy");
else if (ox == oy)
Debug.WriteLine("ox == oy");
else
Debug.WriteLine("ox > oy");
}
Please note that dynamic
is like an object
in many cases, but will defer until runtime the exact binding and handling. This means that the above code would throw an exception at runtime if ox
and/or oy
happen to be types that doesn't know how to be compared.
Upvotes: 1
Reputation: 8894
Convert.ToDouble(ox).CompareTo(Convert.ToDouble(oy));
This will of course throw an InvalidCastException
if one of them is not a number.
Upvotes: 0
Reputation: 111870
There is an interface, IComparable, for that
Defines a generalized type-specific comparison method that a value type or class implements to order or sort its instances.
and
All numeric types (such as Int32 and Double) implement IComparable, as do String, Char, and DateTime. Custom types should also provide their own implementation of IComparable to enable object instances to be ordered or sorted.
You could write...
int ix = 1;
int iy = 2;
object ox = ix;
object oy = iy;
IComparable cx = ox as IComparable;
// Does our type supports comparison?
if (cx == null && ox != null)
{
throw new NotSupportedException();
}
if ((cx != null && cx.CompareTo(oy) < 0) || (ox == null && oy != null)) // x < y
{
}
Note the special case handling for ox == null
Mmmh... shorter..
int cmp = System.Collections.Comparer.Default.Compare(ox, oy);
if (cmp < 0) {
}
It seems that the System.Collections.Comparer
does everything necessary (using the IComparable
interface)
You can even use
int cmp = System.Collections.Generic.Comparer<object>.Default.Compare(ox, oy);
The object
type doesn't support the IComparable<object>
, so the IComparer
interface will be used (in truth, in the .NET 4.5 implementation, the Comparer<object>.Default
will use the Comparer.Default
of the previous example :-) )
IMPORTANT: in all these cases, ox
and oy
MUST be of the same type (or null
). You CAN'T mix int
and double
.
Upvotes: 4