Ограничение универсальных типов в C#

у меня есть универсальный класс MyClass<T> здесь T должны только быть теми типами, которые можно сравнить.

это будет означать только числовые типы и классы, в которых были определены методы для реляционных операторов. Как мне это сделать ?

4 ответов


нельзя ограничить операторами, но можно ограничить интерфейсами. Поэтому, намереваясь использовать >=, <=, == отсутствует, но вы можете использовать CompareTo, Equals.

where T : IComparable<T>

документация по интерфейсу

этот интерфейс приносит вам CompareTo метод, который полезен для реляционного упорядочения (больше, меньше и т. д.). Примитивы и строки уже реализуют это, но вам нужно будет реализовать это для ваших собственных пользовательских типов. Ты бы использовал это вот так.

void SomeMethod<T>(T alpha, T beta) where T : IComparable<T>
{
    if (alpha.CompareTo(beta) > 0) 
    {
        // alpha is greater than beta, replaces alpha > beta
    }
    else if (alpha.CompareTo(beta) < 0)
    {
        // alpha is less than beta, replaces alpha < beta
    }
    else 
    {
        // CompareTo returns 0, alpha equals beta
    }
}

Equals вы получаете по умолчанию как виртуальный метод на object. Вы хотите переопределить этот метод для собственных пользовательских типов, если хотите использовать что-то другое, кроме ссылочного равенства. (Также настоятельно рекомендуется переопределить GetHashCode в то же время.)


можно ограничить универсальный тип только классами, реализующими интерфейс IComparable с помощью модификатора where.

public class MyClass<K> where K : IComparable
{
  ....
}

Если вы хотите ограничить его вещами, которые можно сравнить, вы можете делать такие вещи, как:

public class MyClass<T> where T:IComparable

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

Это проблема, которую я должен решать очень часто, так как примитивные типы данных в C# не имеют "числового" типа данных, как часто предлагалось и требовалось другими здесь.

возможно, следующий выпуск C# будет иметь это, но я сомневаюсь...