Разработка приложений на языке C#. Полезные настройки. Особые спецификаторы формата, страница 20

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

Теперь, когда стало ясно, что от нас требуется, внесите изменения в класс Man. Он должен происходить от интерфейса IComparable и иметь метод CompareTo. Измените строку с объявлением класса:

public class Man : IComparable

Введите в состав класса новый метод. Это можно сделать с помощью меню правой кнопки мыши.

public int CompareTo (object other)     // Метод, реализующий функциональность интерфейса IComparable

{

  return // Сюда вставьте нужный код

}

В теле метода не надо изобретать ничего нового. Пользуйтесь готовым решением. Класс string, объектом которого является поле данных name, уже реализует интерфейс IComparable, поэтому перепоручите ему сравнение имен двух объектов. Этого достаточно для того, чтобы включить возможность сортировки массива по имени. Опробуйте новую функциональность.

//==== Создайте массив

Console.WriteLine("Men before Sort:\n");

   //==== Выведите массив

Array.Sort (men); // Для сортировки пользуемся статическим методом класса Array

Console.WriteLine("\n\nMen after Sort:\n");

//==== Выведите массив

Метод Sort объявлен в классе Array как static, поэтому мы его вызываем по имени класса, а не с помощью объекта. Для сортировки по возрасту используйте поле age. Подумайте, как добавить возможность изменять способ сортировки (по имени, по возрасту) во время выполнения?

Перечисления (enum)

Способ сортировки объектов класса (по имени или по возрасту), очевидно, должен быть характеристикой всего массива объектов, а не каждого объекта в отдельности. В то же время он должен быть инкапсулирован в классе Man, так как массивы объектов другого типа могут и не иметь полей name и age. Вы уже догадались, что я подвожу вас к мысли о необходимости ввести в класс Man статическую переменную, задающую способ сортировки. Такие переменные являются общими для всех объектов класса и существуют даже если нет ни одного объекта.

Так как количество способов сортировки ограничено, то для хранения текущего способа целесообразно ввести новый тип данных — перечисление (enum). Он более информативен, чем какой-либо другой целый тип. Введите в пространство имен MyConsole новый тип, который, кроме двух очевидных значений (byName, byAge), содержит еще один (он понадобится позже). В класс Man введите объявление новой переменной рассматриваемого типа.

namespace MyConsole

{

public enum SortMode : byte { byName, byAge, byStatus };  // Новый тип данных

public class Man : IComparable

{

  //=== Здесь данные  класса Man

  public static SortMode sortBy = SortMode.byName; // Статическая переменная

public int CompareTo (object other)

  {

   switch (sortBy)     // Выбираем ветвь в зависимости от режима сортировки

   {

                   // Вставьте ваш код . . .

   }

  }

  //=== Здесь следуют другие методы класса Man

}

}

Испытайте сортировку, изменив код функции TestManArray.

Механизм свойств в С#

Для того, чтобы лучше понять необходимость следующего шага в развитии класса Man, попробуйте ответить на вопрос. Что будет, если режим сортировки примет недопустимое значние? Это можно устроить так:

Man.sortBy = (SortMode)40;

Подобная выходка может и не привести к отказу (исключению), если надежно работает блок switch в CompareTo, но сортировка-то не будет выполнена. Проверьте сами. Если мы сделаем переменную sortBy закрытой (private) и одновременно добавим открытое свойство, позволяющее (с предосторожностями) изменять ее значение, то поведение программы станет более логичным, а код более надежным.

Свойство—это особый член класса. Для пользователя он выглядит как открытая для записи или для чтения (или для того и другого одновременно) переменная. Для разработчика—это пара открытых аксессоров (или один из них).

Свойства инкапсулируют данные

Свойства позволяют управлять состоянием объектов, создавая иллюзию того, что поля данных открыты (public). На самом деле доступ к полям ведется с помощью пары методов (get_ИмяСвойства, set_ИмяСвойства). Отсоединив состояние объектов от методов доступа к нему, мы получаем свободу выбора в способе реализации свойства.