Suppose there is a class A

class A:IComparable { int pole1; int pole2; public int CompareTo(A other) { return this.pole1.CompareTo(other.pole1); } } 

And there is class B

 class B<T> { T[] arr; public void Sort() { Array.Sort(arr); } } 

Class B contains an array of objects of class A.
The question is, when I call the sorting of a class B object from Maine, they will all be sorted by the field pole1 . It is logical, because I pointed out that way.
How to make the sorting go according to the user's choice, i.e. sort by pole1 or pole2 .
I think so, you need to somehow indicate the sign, but I do not understand how to implement it. Tell me how to properly implement the method CompareTo() and Sort()

  • implement 2 comparators and pass the necessary one. Or something smarter you want? - pavel
  • Like Array.Sort (arr); will understand which comparator to use? - Pyrejkee
  • I already read, I did not understand there, so I would not have asked a question here. - Pyrejkee
  • 2 parameter tried to pass in the sort function comparator, the successor of IComparer? As in the example. - pavel

2 answers 2

The Array.Sort function has an overload; the host delegate is the Comparison<T>

Thus you can declare different comparison functions directly inside the class, for example

 class A { int pole1; int pole2; public static int CompareByP1(A a, A b) { return a.pole1.CompareTo(b.pole1); } public static int CompareByP2(A a, A b) { return a.pole2.CompareTo(b.pole2); } } 

And use them as a parameter.

 Array.Sort(b.arr, A.CompareByP2); Array.Sort(b.arr, A.CompareByP1); 

To use from class B, you need to add the parameter Comparison<T> , which will be passed to the sort method

 public void Sort(Comparison<T> comparison) { Array.Sort(arr, comparison); } 

And used like

 b.Sort(A.CompareByP2); 
  • Can I do something here so that the sign would be passed without specifying class A? Because Class B can hold in itself not only an array of classes A, but other classes as well, as I indicated in the question and indicated this template field. - Pyrejkee
  • @ KirillKiryanchikov, Updated the answer - Grundy
  • That is so necessary! Thank you very much;) - Pyrejkee

I read MSDN did it and it works.

 class ComparePole2 : IComparer<A> // объявляем класс который реализует IComparer { public int Compare(A x, A y) //Сравниваем по pole2. { return x.pole2.CompareTo(y.pole2); } } class A : IComparable<A> { public int pole1; public int pole2; public int CompareTo(A obj) { return pole1.CompareTo(obj.pole1); } } class B<A> { public A[] arr; } Array.Sort(b.arr); // Сортируем по pole1. Array.Sort(b.arr,new ComparePole2); // Сортируем по pole2. 
  • Something completely different. If I have 10 fields, so what are the classes then 10 pieces to implement? Plus, class A and B fields are encapsulated in me, they should not be accessible from outside. Thanks for the advice, but it does not fit. - Pyrejkee
  • @ KirillKiryanchikov the question was how to sort by pole1 or pole2 and how to implement CompareTo () and Sort (). I answered them. At the expense of 10 fields I do not know if they were open, you could just use Linq. You can always subclass ComparePole2 where you need it. - Evgeny Kidyaev
  • It's just that for me it is somehow not practical, to create a class for each field being sorted, for sure there are more elegant solutions. - Pyrejkee
  • @ KirillKiryanchikov Linq - b.arr.OrderBy (x => x.poleX); Very graceful. - Evgeny Kidyaev
  • Unfortunately, I hear about Linq for the first time and in my task I need to do without this function. - Pyrejkee