Общее ограничение для сопоставления числовых типов

Я пытаюсь написать метод расширения для числовых типов, которые будут использоваться в беглой структуре тестирования, которую я создаю. В принципе, я хочу сделать это:

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 и т.д.