如何在 C# 中对未知类型的盒装数字使用比较运算符?

How can I use comparison operators with boxed numerics of unknown types in c#?

我想构建比较两个对象的值的函数,并且其行为与内置的比较运算符相同。我无法 在编译时知道对象的类型并且只能将它们作为对象访问。由于这些原因,任何依赖于将它们转换为底层类型或将函数更改为泛型的解决方案都无济于事。

我天真的第一个实现是这样的:

bool LessThan(object left, object right) {
    return left < right;
}

但不幸的是,这会导致错误

error CS0019: Operator `<' cannot be applied to operands of type `object' and `object'

然后我尝试使用 LINQ 表达式

bool LessThan(object left, object right) {
    BinaryExpression expression = Expression.Equal(Expression.Constant(left), Expression.Constant(right));
    return (bool) Expression.Lambda(expression).Compile().DynamicInvoke());
}

当两个对象具有相同的类型但您收到类似

的错误时,该方法有效
System.InvalidOperationException : The binary operator LessThan is not defined for the types 'System.Single' and 'System.Double'.

当对象具有不同类型时。

是否可以将它们都转换为双精度值然后进行比较?

bool LessThan(object left, object right) {
    return ((double) Convert.ChangeType(left, typeof(double))
         < ((double) Convert.ChangeType(right, typeof(double));
}

这似乎给出了所需的行为,但我怀疑在某些情况下转换会导致信息丢失。

有更好的解决方案吗?

我认为最懒惰的解决方案是:

bool LessThan(dynamic left, dynamic right) {
    return left < right;
}

如果这两种类型确实无法比较,这当然会产生运行时异常。

This seems to give the desired behavior but I suspect that the conversions will lead to information loss in some cases.

如果比较 DoubleSingle,C# 无论如何都会将 Single 转换为 Double。否则无法比较它们。