There is the following generalized class (it has not been fully implemented yet):

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) { } } 

The idea is as follows: I want to implement a quick sort algorithm for given data types (for integer, real, character). I would like to do it in one class. I thought of using a generic class, but in the process of writing code I encountered the problem of comparing variables of a generalized type. Operator overloading for Type not possible in the QuickSorter class. Is there a way to implement overloading of comparison operators for Type in a generic class? Maybe there is another suitable solution for this problem?

  • five
    Most likely it is better to set a limit on type-parameter for generic with some IComparable or IComparable<T> - Grundy
  • Agree with @Grundy. Operator overloading is a story from C ++, and it’s a chore. Easier to implement w / a interfaces. - Bulson
  • 2
    look here ru.stackoverflow.com/q/487814/198316 , the question is how to use the comparison without operators - rdorn
  • @Grundy as shown by personal experience - this is the only adequate option - rdorn
  • 6
    Instead of Type select another one, for example T This class (Type) is already in C # - Vadim Prokopchuk

2 answers 2

In C #, properties, indexers, events, operator methods , constructors, and destructors cannot have type parameters . However, they can be defined in a generic type in order to use the type parameters of this type in their code. C # does not support specifying your own generic type parameters for these members, since the creators of C # from Microsoft believe that developers are unlikely to use these members as generic ones. In addition, to support the generalized use of these members in C #, we would have to develop a special syntax, which is quite expensive. For example, when used in the code operator + compiler may cause an overloaded operator method. It is impossible to indicate in the code, where there is an operator + , any type arguments.


Note: The Microsoft recommendations for designers state that parameter variables should be called T or, as a last resort, begin with T (as, for example, TKey or TValue ). T means type (type), and I means interface (for example, IComparable )


As correctly noted @Qwertiy:

Imposing restrictions on static C # members does not allow

And comparison operators must be static. To solve the problem, you can impose a restriction on the class, for example, class QuickSorter<T> where T : IComparable<T> , which limits the use of the class only to those types in which the IComparable<T> interface is IComparable<T>

All primitive types, except Object , Boolean , implement the IComparable interface and IComparable<T> . Type Boolean - implements only IComparable .

What does this give? In comparison operators, you call the CompareTo method on compared instances. For primitive types, everything will work, for its types, you will have to implement this interface.


I would like to add: do not use the Type name as the name of the generic type, since this type is defined in the mscorlib.dll assembly, the System namespace. Misunderstandings may arise in the future.

  • Thanks for the clear explanation! Type I used the habit of the fact that it is recommended to give names to types and variables meaningful. But now I understand why msdn recommends setting T instead of Type . - Andrei Khotko
 class QuickSorter<Type> 
 class QuickSorter<Type> where Type : IComparable<Type> 

Now you can call CompareTo on objects, which compares them.

And to impose restrictions on static members C # does not allow.

  • Thank! It turns out that everything is so simple. And if I want to add the implemented ISorter interface for the QuickSorter<T> ISorter , then where should I put it in the class QuickSorter<T> where T : IComparable<T> line class QuickSorter<T> where T : IComparable<T> ? - Andrei Khotko
  • @AndreiKhotko, comma separated? - Qwertiy