Как я могу использовать операторы сравнения с коробочными числами неизвестных типов в 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));
}
Это, кажется, дает желаемое поведение, но я подозреваю, что преобразования в некоторых случаях приведут к потере информации.
Есть идеи для лучших решений?
1 ответ
Я думаю, что самое ленивое решение:
bool LessThan(dynamic left, dynamic right) {
return left < right;
}
Это, конечно, сгенерирует исключение во время выполнения, если два типа действительно нельзя сравнить.
Это, кажется, дает желаемое поведение, но я подозреваю, что преобразования в некоторых случаях приведут к потере информации.
Если вы сравните Double
и Single
, C# преобразует Single
к Double
тем не мение. Их нельзя сравнивать иначе.