
- •Глава 9. Методы с#
- •9.1. Методы-процедуры и методы-функции
- •9.2. Соотношение фиксированных параметров и аргументов
- •9.3. Параметры с типами ссылок
- •1 4 8 2 4 9 3
- •1 2 3 4 4 8 9
- •1 4 9 16 25 36
- •9.4. Методы с переменным числом аргументов
- •9.5. Перегрузка методов
- •9.6. Рекурсивные методы
- •9.7. Применение метода Array.Sort()
9.7. Применение метода Array.Sort()
Несмотря на то, что обоснования возможности использования имени метода в качестве аргумента другого метода, будут рассмотрены только в главе, посвященной делегатам, уже сейчас полезно научиться применять собственные методы для «настройки» некоторых методов библиотечных классов. Сделаем это на примере очень полезного метода Array.Sort(), который мы упомянули в главе 7. Это статический метод, упорядочивающий элементы массива. Этот метод перегружен, и в классе Array определены 17 методов Sort() с разными сигнатурами. Тривиальный вариант метода Sort() имеет только один параметр типа Array. Так как все типы массивов являются наследниками класса Array, то в качестве аргумента при обращении к методу сортировки допустимо использовать ссылку на любой одномерный массив. (Имеется ввиду одномерный массив с элементами любых типов.) В зависимости от типа элементов массива-аргумента метод Sort() упорядочивает их. Массивы с элементами арифметических типов упорядочиваются по возрастанию значений, строки сортируются лексикографически и т.д.
Такое «поведение» метода Sort() с одним параметром очень полезно, но этого зачастую недостаточно для конкретных задач. Рассмотрим ещё один вариант метода сортировки, в котором после ссылки на сортируемый массив в качестве второго аргумента применяется имя функции, задающей правило сравнения элементов. Такую функцию программист-пользователь должен написать самостоятельно по следующей схеме.
int имя_функции(тип параметр_1, тип параметр_2)
{ if(условие 1) return +1; // нарушен порядок if (условие 2) return -1; // порядок соблюдён return 0; // безразличие
}
Имя_функции выбирается произвольно. Тип возвращаемого значения int, тип параметров должен быть тем же, что и у элементов сортируемого массива. Условия 1 и 2 - логические выражения, в которые входят параметры 1 и 2. Обычно это отношения между параметрами.
Получив в качестве аргумента имя такой функции, метод Sort() применяет её для принятия решения об относительной упорядоченности пар элементов сортируемого массива. Делается это приблизительно (мы ведь не знаем алгоритма работы метода Sort()) так. Если результат равен 0, то сравниваемые элементы равнозначны, их не нужно менять местами. Если результат равен +1, то первый параметр должен быть помещён после второго. При результате -1 первый параметр должен размещаться до второго.
В следующей программе две функции сравнения реализованы в виде статических методов класса, где размещён метод Main(). Первая функция even.odd() проверяет чётность своих параметров и возвращает +1, если первый параметр нечётный, а второй - чётный. При равенстве параметров возвращается 0, а при ложности обоих условий возвращается -1. Получение -1 означает, что первый параметр чётный - его никуда не нужно перемещать. Таким образом, функция «приказывает» методу Array.Sort() так поместить элементы массива, чтобы вначале находились чётные, а за ним нечётные значения.
Вторая функция drop() «настраивает» метод сортировки на упорядочение массива по убыванию значений его элементов. Значение +1 возвращается в том случае, если первый параметр меньше второго.
В методе Main() определен и инициализирован целочисленный массив, который трижды сортируется методами Sort(). Первый раз по чётности, второй раз по возрастанию, третий раз по убыванию значений элементов. После каждой сортировки выводятся значения элементов на консольный экран.
Текст программы и полученные результаты поясняют сказанное.
// 09_18.cs - применение метода Array.Sort()
static int even_odd(int x, int y) // по четности
{
if (x % 2 != 0 & y % 2 == 0)
return 1;
if (x == y)
return 0;
return -1;
}
static int drop(int x, int y) // по убыванию
{
if (x < y)
return 1;
if (x == y)
return 0;
return -1;
}
static void Main09_18()
{
int[] ar = { 4, 5, 2, 7, 8, 1, 9, 3 };
Array.Sort(ar, even_odd); // по четности
foreach (int memb in ar)
Console.Write("{0} ", memb);
Console.WriteLine();
Array.Sort(ar); // по умолчанию - по возрастанию
foreach (int memb in ar)
Console.Write("{0} ", memb);
Console.WriteLine();
Array.Sort(ar, drop); // по убыванию
foreach(int memb in ar)
Console.Write("{0} ", memb);
Console.WriteLine();
}
Результат выполнения программы:
48257193
12345789
98754321