Универсальное ограничение для соответствия числовым типам [дубликат]

Этот вопрос уже имеет ответ здесь:

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

public static ShouldBeGreaterThan(this T actual, T expected, string message)
    where T : int || T: double || etc...

Просто where T : struct не делает, так как это будет также соответствовать string и bool, и возможно что-то еще я забываю. есть ли что-то, что я могу сделать для соответствия только числовым типам? (Конкретно типы, которые реализуют > и < операторы, таким образом, я могу сравнить их... Если это означает, что я соответствую датам также, это действительно не имеет значения - расширение все еще сделает то, что я ожидаю.)

78
задан Tomas Aschan 25 July 2010 в 14:38
поделиться

5 ответов

В этом случае вы хотите ограничить свой универсальный интерфейс интерфейсом IComparable , который дает вам доступ к методу CompareTo , поскольку этот интерфейс позволяет вам ответьте на вопрос ShouldBeGreaterThan .

Числовые типы реализуют этот интерфейс, и тот факт, что он также работает со строками, не должен вас сильно беспокоить.

55
ответ дан 24 November 2019 в 10:37
поделиться

Stackoverflow завален вопросами такого рода. Посмотрите на этот поиск. C# не поддерживает способ определения общего типа, ограниченного числами. К сожалению, лучший выход - реализовать метод расширения для всех объектов и сделать переключатель на основе типа или создать набор методов для ints, doubles, floats и т.д.

4
ответ дан 24 November 2019 в 10:37
поделиться
where T : struct, 
          IComparable, 
          IComparable<T>, 
          IConvertible, 
          IEquatable<T>, 
          IFormattable

Это самое близкое к числовому ограничению, которое я могу найти. Все числовые типы реализуют эти 5 интерфейсов, но IFormattable не реализуется с помощью bool, а строки являются ссылочным типом, поэтому они не применимы.

Есть и другие вещи, которые реализуют это - например, DateTime, так что это не совсем то, что требуется, но предотвращает множество нежелательных экземпляров.

43
ответ дан 24 November 2019 в 10:37
поделиться

Трудно ограничиться только числами, поскольку нет ничего общего, вроде INumeric, чтобы использовать в качестве фильтра. На самом деле, я подозреваю, что самый простой подход здесь - не настаивать на ограничении, и использовать Comparer.Default.Compare внутри метода.

Этот встроенный тип поддерживает как generic IComparable, так и не generic IComparable, а также поддерживает ref-типы, value-типы и использование lifted через Nullable.

Для полного использования operator посмотрите MiscUtil's Operator class и GreaterThan etc, которые могут быть полезны, если вы действительно хотите использовать оператор (а не интерфейс). Он также предоставляет доступ к другим операторам, таким как Add и т.д.

6
ответ дан 24 November 2019 в 10:37
поделиться
public static bool IsGreaterThan<T>(this T actual, T comp) where T : IComparable<T>
{
    return actual.CompareTo(comp) > 0;
}

Вы можете добавить ограничение struct, если хотите.

16
ответ дан 24 November 2019 в 10:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: