На этом шаге мы рассмотрим особенности реализации таких методов.
Допустим, мы хотим описать метод, который вычисляет сумму переданных ему аргументов. В принципе, путем перегрузки метода мы можем описать версию с одним аргументом, двумя аргументами, тремя аргументами и так далее. Проблема в том, что на каждое количество аргументов нужна "персональная" версия метода. И сколько бы версий метода мы ни описали, всегда можно передать на один аргумент больше. Здесь мы сталкиваемся с проблемой, которая состоит в том, что наперед не известно, сколько аргументов будет передано методу при вызове. Причем мы хотим, чтобы можно было передавать любое количество. Именно для подобных случаев в С# есть механизм, позволяющий описывать методы с произвольным количеством аргументов. Набор аргументов, количество которых неизвестно, формально описывается как массив, но только перед описанием этого массива в списке аргументов указывается ключевое слово params. В теле метода обрабатываются такие аргументы, как элементы массива. Но при вызове метода аргументы просто перечисляются через запятую. Например, если некоторый метод описан в формате
метод(params int[] args),
Метод можно описывать так, что в нем будут как "обычные" (явно описанные) аргументы, так и аргументы, количество которых наперед не задано. В таком случае "обычные" аргументы описываются сначала. Допустим, мы хотим описать метод, которому при вызове обязательно передаются один символьный аргумент и произвольное количество целочисленных аргументов. Такой метод описывается в формате
(char symb, params int[] args).
Небольшая программа, иллюстрирующая способы описания и использования методов с произвольным количеством аргументов, представлена ниже.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace pr73_1 { class Program { // Метод для вычисления суммы чисел: static int sum(params int[] a){ // Локальная переменная (значение суммы): int res = 0; // Перебор аргументов метода: for (int k=0; k < a.Length; k++) { // Прибавление слагаемого к сумме: res += a[k]; } // Результат метода: return res; } // Метод для извлечения символов из текста: static string getText(string t, params int[] a){ // Начальное значение формируемой текстовой строки: string res=""; // Перебор аргументов метода: for(int k=0; k < a.Length; k++){ // Добавление символа в текст: res += t[a[k]]; } // Результат метода: return res; } // Метод отображает значения аргументов: static void show(int[] a, params char[] b) { // Количество элементов в числовом массиве: Console.Write("Чисел " + a.Length + ": "); // Значения элементов в числовом массиве: for(int k=0; k < a.Length-1; k++){ Console.Write(a[k] + " "); } Console.WriteLine("и " + a[a.Length-1]); // Количество символьных аргументов: Console.Write("Символов " + b.Length + ": "); // Значения символьных аргументов: for(int k=0; k < b.Length-1; k++){ Console.Write(b[k] + " "); } Console.WriteLine("и " + b[b.Length-1]); } // Главный метод программы: static void Main() { // Примеры вызова методов. // Вычисление суммы чисел: Console.WriteLine("Сумма чисел: " + sum(1, 6, 9, 2, 4)); Console.WriteLine("Сумма чисел: " + sum(5, 1, 2)); // Формируется текст: Console.WriteLine(getText("Раз два три", 0, 10, 8, 1)); Console.WriteLine(getText("Бревно", 3, 5, 1, 5, 4)); // Отображаются аргументы: show(new int[] {1, 3, 5}, 'А', 'В', 'С', 'D', 'Е'); show(new int[] {1, 3, 5, 7, 9}, 'А', 'В', 'С', 'D') ; // Задержка: Console.ReadLine(); } } }
Как будет выглядеть результат выполнения этой программы, показано ниже:
Рис.1. Результат выполнения программы
В программе описан статический метод sum(), предназначенный для вычисления суммы чисел, переданных аргументами методу. Аргумент описан как
params int[] а; .
res += a[k];
sum(1, 6, 9, 2, 4); ,
sum(5, 1, 2);
Метод getText() предназначен для формирования одной текстовой строки на основе другой текстовой строки. Аргументом методу передается текст (первый аргумент) и произвольное количество целочисленных аргументов. Эти целочисленные аргументы определяют индексы символов в текстовой строке (первый аргумент), из которых следует сформировать строку-результат. Например, если метод вызывается командой
getText("Раз два три", 0, 10, 8, 1); ,
getText ("Бревно", 3, 5, 1, 5, 4); ,
Код метода getText() реализован несложно. Объявляется текстовая переменная res, начальное значение которой пустая текстовая строка. Затем запускается конструкция цикла, в которой перебираются целочисленные аргументы метода (отождествляются с элементами массива а). Командой
res += t[а[k]];
Метод show() выполняет незатейливую работу - он отображает значения переданных ему аргументов. Первым аргументом методу передается целочисленный массив а (обычный). После этого обязательного аргумента методу может передаваться произвольное количество символьных аргументов. Поэтому формальный второй аргумент b метода описан как массив с идентификатором params. Методом при вызове отображается такая информация:
Для проверки работы метода использованы команды
show(new int[] {1, 3, 5}, 'А', 'В', 'С', 'D', 'Е')
show(new int[] {1, 3, 5, 7, 9}, 'А', 'В', 'С', 'D').
new int[] {значения}.
new int[] {1, 3, 5};
На следующем шаге мы рассмотрим главный метод программы.