Search code examples
c#objectprimitive-typesboxingicomparable

Dynamic comparison of boxed primitive values


I need to generic compare two primitive (numeric!) types (both boxed as object) to find the greater one. I can't use generics, because I only get objects, but I know the unboxed values are primitive numbers (int, short, long, float etc), so I can cast to IComparable.

How can I than compare those? CompareTo() throws an error because they are different types, but ChangeType can cause an OverflowException...?

        public static int Compare(object value1, object value2)
    {
        //e.g. value1 = (object)(int)1; value2 = (object)(float)2.0f
        if (value1 is IComparable && value2 is IComparable)
        {
            return (value1 as IComparable).CompareTo(value2);
            //throws exception bc value1.GetType() != value2.GetType()
        }
        throw new ArgumentException();
    }

Solution

  • Maybe so

    public static int Compare(object value1, object value2)
    {
        if (value1 is double || value2 is double)
        {
            double d1 = Convert.ToDouble(value1);
            double d2 = Convert.ToDouble(value2);
            return d1.CompareTo(d2);
        }
    
        if (value1 is float || value2 is float)
        {
            float f1 = Convert.ToSingle(value1);
            float f2 = Convert.ToSingle(value2);
            return f1.CompareTo(f2);
        }
    
        long x1 = Convert.ToInt64(value1);
        long x2 = Convert.ToInt64(value2);
        return x1.CompareTo(x2);
    }
    

    The byte, short, int types can be converted to long without precision loss.