I want to build functions that compare the values of two objects and behave identically to the built in comparison operators. I cannot know the types of the objects at compile-time and only have access to them as objects. Any solution that relies on casting them to their underlying types or changing the function to be a generic would not be helpful for these reasons.
My naive first implementation would be something like:
bool LessThan(object left, object right) {
return left < right;
}
but unfortunately this results in the error
error CS0019: Operator `<' cannot be applied to operands of type `object' and `object'
I then tried using LINQ expressions
bool LessThan(object left, object right) {
BinaryExpression expression = Expression.Equal(Expression.Constant(left), Expression.Constant(right));
return (bool) Expression.Lambda(expression).Compile().DynamicInvoke());
}
which works when the two objects have the same type but you get an error like
System.InvalidOperationException : The binary operator LessThan is not defined for the types 'System.Single' and 'System.Double'.
when the objects have different types.
Is it OK to convert them both to doubles and then do the comparison?
bool LessThan(object left, object right) {
return ((double) Convert.ChangeType(left, typeof(double))
< ((double) Convert.ChangeType(right, typeof(double));
}
This seems to give the desired behavior but I suspect that the conversions will lead to information loss in some cases.
Any ideas for better solutions?
I think the laziest solution is:
bool LessThan(dynamic left, dynamic right) {
return left < right;
}
This will of course generate a runtime exception if the 2 types really cannot be compared.
This seems to give the desired behavior but I suspect that the conversions will lead to information loss in some cases.
If you compare a Double
and a Single
, C# will convert the Single
to a Double
anyway. They cannot be compared otherwise.