Общее ограничение для сопоставления числовых типов
Я пытаюсь написать метод расширения для числовых типов, которые будут использоваться в беглой структуре тестирования, которую я создаю. В принципе, я хочу сделать это:
public static ShouldBeGreaterThan<T>(this T actual, T expected, string message)
where T : int || T: double || etc...
Просто where T : struct
не работает, так как это также будет соответствовать string
и bool
, и, возможно, что-то еще я забываю. есть ли что-то, что я могу сделать, чтобы соответствовать только числовым типам? (В частности, типы, которые реализуют операторы >
и <
, поэтому я могу их сравнить... Если это означает, что я также сопоставляю даты, это не имеет большого значения - расширение будет по-прежнему делать то, что я ожидаю. )
Ответы
Ответ 1
В этом случае вы хотите ограничить свой общий интерфейс IComparable
, который дает вам доступ к методу CompareTo
, так как этот интерфейс позволяет ответить на вопрос ShouldBeGreaterThan
.
Числовые типы реализуют этот интерфейс и тот факт, что он также работает с строками, не должен сильно вас беспокоить.
Ответ 2
where T : struct,
IComparable,
IComparable<T>,
IConvertible,
IEquatable<T>,
IFormattable
Что ближе всего я могу получить числовое ограничение. Все числовые типы реализуют эти 5 интерфейсов, но IFormattable не реализуется bool, а строки являются ссылочным типом, поэтому они неприменимы.
Есть и другие вещи, которые реализуют эти - DateTime, например, так что это не так, как требуется, но предотвращает много запросов, которые вы не хотите.
Ответ 3
public static bool IsGreaterThan<T>(this T actual, T comp) where T : IComparable<T>
{
return actual.CompareTo(comp) > 0;
}
Вы также можете добавить ограничение struct, если хотите.
Ответ 4
Трудно ограничиться только числами, поскольку нет ничего общего с INumeric
можно использовать в качестве фильтра. На самом деле, я подозреваю, что самый простой подход здесь состоит в том, чтобы не настаивать на ограничении и использовать Comparer<T>.Default.Compare
внутри метода.
Этот встроенный тип поддерживает как универсальный IComparable<T>
и неуниверсальный IComparable
, а также поддерживает ref-типы, значения-типы и отмененное использование через Nullable<T>
.
Для полного использования оператора посмотрите на класс MiscUtil Operator
GreaterThan и GreaterThan
Д., GreaterThan
могут быть полезны, если вы действительно хотите использовать оператор (а не интерфейс). Он также предоставляет доступ к другим операторам, таким как Add
и т.д.
Ответ 5
Stackoverflow завален таким вопросом. Посмотрите на этот поиск. С# не поддерживает способ определения общего типа, ограниченного числами. К сожалению, ваш лучший выбор - реализовать метод расширения для всех объектов и сделать переключатель на основе типа или создать набор методов для int, double, floats и т.д.
Ответ 6
Обходной путь может помочь: Обходной путь с использованием политик. Он обеспечивает безопасность времени компиляции.