Сортировка по нескольким полям в одном компараторе?

Есть пример компаратора. Как сделать так, чтоб он работал для всех полей класса?(по выборочному, чтоб не писать под каждое поле свой компаратор)
public class Book
  {
    private string name;
    private string author;
    private int releaseDate;
    
    public int CompareTo(Book book)
    {
      if (book != null)
      {
        return name.CompareTo(book.name);
      }
      else
      {
        throw new Exception("Невозможно сравнить два объекта");
      }
    }
  }
  • Вопрос задан
  • 1925 просмотров
Решения вопроса 1
@Mercury13
Программист на «си с крестами» и не только
Не понял. Если по одному, при равенстве — по другому, если всё ещё равны — по третьему, то примерно так.
public int CompareTo(Book book)
    {
      if (book != null)
      {
        int r = name.CompareTo(book.name);
        if (r != 0)
          return r;
        r = author.CompareTo(book.author);
        if (r != 0)
          return r;
        return Math.sign(releaseDate - book.releaseDate);
      }
      else
      {
        throw new Exception("Невозможно сравнить два объекта");
      }
    }


Если же вы хотите, чтобы, в зависимости от каких-то настроек, сортировало то по названию, то по автору, сделайте коллекцию разнотипных объектов.
const int NAME = 0, AUTHOR = 1, COUNT = 2;

class ByName : Comparer<Book> {}
class ByAuthor : IComparer<Book> {}

Comparer<Book> comparers[COUNT] = {  new ByName(), new ByAuthor() };

C# знаю плохо, возможны синтаксические ошибки.

Третий вариант — для полей одинаковых типов сделать унифицированный доступ.
const int S_NAME = 0, S_AUTHOR = 1, S_COUNT = 2;
const int I_DATE = 0;

public class Book
{
    string stringFields[S_COUNT];
    int intFields[I_COUNT];

    public string name {
        get { return stringFields[S_NAME; ] }
        set { stringFields[S_NAME] = value; }
    }
}

class StringComparer : IComparer<Book> {
   int code;
   StringComparer(int aCode) { code = aCode; }
   int Compare(Book a, Book b) { return a.stringFields[code].compareTo(b.stringFields[code]); }
}

const int ALL_NAME = 0, ALL_AUTHOR = 1, ALL_DATE=2, ALL_COUNT = 3;

Comparer<Book> comparers[ALL_COUNT] = {  
   new StringComparer(S_NAME), new StringComparer(S_AUTHOR), new IntComparer(I_DATE) };
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы