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