C#. Можно ли перегрузить операторы сравнения в обобщенных классах?

275
31 января 2017, 19:38

Есть следующий обобщенный класс (он пока не реализован до конца):

class QuickSorter<Type>
{
    private void Swap(ref Type a, ref Type b)
    {
        Type temp = a;
        a = b;
        b = temp;
    }
    public void Sort(Type[] Array)
    {
        //Sort_Recursion(Array);
    }
    private void Sort_Recursion(Type[] Array, int L, int R)
    { 
        /*
        Type Median = Array[L + (R - L)/2]; // (L + R)/2 = L/2 + R/2 = L - L/2 + R/2 = L + (R - L)/2 ==> Для избежания переполнения
        int l = L;
        int r = R; 
        while (l <= r)
        {
            while (Array[l] < Median)
        }
        */    
    }
    public static bool operator >(Type a, Type b)
    {
    }
    public static bool operator <(Type a, Type b)
    {
    }
}

Идея следующая: я хочу реализовать алгоритм быстрой сортировки для заданных типов данных (для целочисленных, вещественных, символьных). Хотел бы сделать это в одном классе. Подумал воспользоваться обобщенным классом, но в процессе написания кода столкнулся с проблемой сравнения переменных обобщенного типа. Перегрузка операторов для типа Type невозможна в классе QuickSorter. Есть ли способ реализовать перегрузку операторов сравнения для типа Type в обобщенном классе? Может быть, есть другое подходящее решение для данной задачи?

Answer 1
class QuickSorter<Type>
class QuickSorter<Type> where Type : IComparable<Type>

Теперь ты сможешь на объектах вызывать CompareTo, который их и сравнивает.

А накладывать ограничения на статические члены C# не позволяет.

Answer 2

В языке C# у свойств, индексаторов, событий, операторных методов, конструкторов и деструкторов не может быть параметров-типов. Однако их можно определить в обобщенном типе с тем, чтобы в их коде использовать параметры-типы этого типа. C# не поддерживает задание собственных обобщенных параметров типа у этих членов, поскольку создатели языка С# из компании Microsoft считают, что разработчикам вряд ли потребуется задействовать эти члены в качестве обобщенных. К тому же для поддержки обобщенного использования этих членов в С# пришлось бы разработать специальный синтаксис, что довольно затратно. Например, при использовании в коде оператора + компилятор может вызвать перегруженный операторный метод. Невозможно указать в коде, где есть оператор +, какие бы то ни было аргументы типа.

Примечание: В рекомендациях Microsoft для проектировщиков указано, что переменные параметров должны называться T или, в крайнем случае, начинаться с T (как, например, TKey или TValue). T означает тип (type), а I означает интерфейс (например, IComparable)

Как правильно заметил @Qwertiy:

Накладывать ограничения на статические члены C# не позволяет

А операторы сравнения должны быть статическими. Для решения проблемы можно наложить ограничение на класс, например class QuickSorter<T> where T : IComparable<T>, что ограничит использование классом только тех типов, в которых определен интерфейс IComparable<T>

Все примитивные типы, кроме Object, Boolean, реализуют интерфейс IComparable и IComparable<T>. Тип Boolean - реализует только IComparable.

Что это дает? В операторах сравнения, вы вызываете метод CompareTo на сравниваемых экземплярах. Для примитивных типов все будет будет работать, для своих типов придется реализовать этот интерфейс.

Хотелось бы еще добавить: не используйте имя Type как имя обобщенного типа, поскольку этот тип определен в сборке mscorlib.dll, пространство имен System. В будущем может возникнуть недопонимание.

READ ALSO
Краш билда при запуске на Sony xperia XZ, libeGL : error 3009 (EGL_BAD_MATCH)

Краш билда при запуске на Sony xperia XZ, libeGL : error 3009 (EGL_BAD_MATCH)

Веду разработку на unity3d, скрипты пишу на с#, опыт разработки у меня крайне небольшойБилд вылетает при запуске на телефоне Sony xperia XZ (на explay fire все...

283
Что это за синтаксис в передаче параметра - &ldquo;new object[] {s}&rdquo;

Что это за синтаксис в передаче параметра - “new object[] {s}”

Интересует - ,new object[] {s}) Почему s в фигурных скобках?

298
simplexml_load_file тире и массив

simplexml_load_file тире и массив

Интересная ситуация получаетсяИспользую simplexml_load_file

312
не могу удалить индекс mysql

не могу удалить индекс mysql

здравствуйте, не могу удалить индекс столбца из бд

462