Змінна кількість аргументів у методах. Модифікатор params. Переваги. Приклади методів зі змінною кількістю аргументів

Змінна кількість аргументів у методах. Модифікатор params. Переваги. Приклади методів зі змінною кількістю аргументів


Зміст



1. Що означає змінна кількість аргументів у методі? Ключове слово param. Загальна форма оголошення методу зі змінною кількістю аргументів

Інколи бувають випадки, коли метод потрібно викликати декілька раз і кожного разу в цей метод потрібно передавати різну кількість аргументів. Таку ситуацію можна обійти створивши перевантажені реалізації методу.
Але не завжди можна знати скільки аргументів буде передаватись в метод, особливо, якщо кількість аргументів може бути досить великою. У цьому випадку метод оголошується зі змінною кількістю аргументів.
Загальна форма оголошення методу зі змінною кількістю аргументів має вигляд:

return_type MethodName(params type[] parameters)
{
  // ...
}

де

  • MethodName – ім’я методу;
  • return_type – тип, що повертає метод;
  • type – тип параметрів, які отримує метод. Кількість параметрів може бути змінною;
  • parameters – ім’я, що відповідає масиву параметрів типу type.

 

2. Які переваги дає використання у методах змінної кількості аргументів?

Використання змінного числа аргументів дає такі переваги:

  • у той самий метод можна передавати різну кількість аргументів. Завдяки цьому зменшується кількість реалізацій методу. Немає потреби в “перевантажених” реалізаціях методу;
  • спрощується програмний код оголошення методу за рахунок узагальненого представлення масиву параметрів з допомогою модифікатора params;
  • число аргументів може бути будь-яким і задаватись по ходу виконання програми (наприклад n аргументів). У випадку “перевантаження” методу, варіанти реалізації методу з різною кількістю аргументів є відомі наперед.

 

3. Приклади методів, що містять змінну кількість аргументів

Приклад 1. Метод Max(), що знаходить максимальне значення між масивом аргументів.

// метод, що знаходить максимальне значення між списком параметрів
double Max(params double[] values)
{
  if (values.Length==0)
  {
    Console.WriteLine("Помилка: немає аргументів у виклику методу");
    return 0;
  }

  double max = 0;
  for (int i = 0; i < values.Length; i++)
    if (max < values[i])
      max = values[i];
  return max;
}

Виклик методу з іншого програмного коду

double maximum;

// знаходження максимуму між 3 значеннями
maximum = Max(8.5, 9.3, 2.9); // maximum = 9.3

// знаходження максимуму між 5 значеннями
maximum = Max(0.3, 2.33, 12.91, 8.93, 7.55); // maximum = 12.91

// знаходження максимуму між 7 значеннями
double[] arguments = { 2.8, 3.6, 1.7, 0.9, 4.45, 7.32, 2.83 };
maximum = Max(arguments); // maximum = 7.32

Приклад 2. Метод SumNegative(), що знаходить суму від’ємних аргументів.

// метод, що знаходить суму від'ємних аргументів
int SumNegative(params int[] p)
{
  int sum = 0;
  for (int i = 0; i < p.Length; i++)
    if (p[i] < 0) sum = sum + p[i];
      return sum;
}

Використання методу в іншому програмному коді

int sum = 0;

// виклик методу з 6 аргументами
sum = SumNegative(-3, 2, -1, 4, -8, 5); // sum = -12

// виклик методу з 7 аргументами
int[] arrayArgs = { -1, 0, -1, 2, -5, -3, 2 };
sum = SumNegative(arrayArgs);

Приклад 3. Реалізація методу IsAscending(), який визначає, чи утворюють аргументи зростаючу послідовність.

// метод, що визначає, чи утворюють аргументи зростаючу послідовність
bool IsAscending(params int[] parameters)
{
  if (parameters.Length < 2)
    return false; // замало аргументів, аргументів має бути більше одного

  for (int i=0; i<parameters.Length-1; i++)
    if (parameters[i]>=parameters[i+1])
      return false;
  return true;
}

Використання методу в іншому програмному коді:

bool fAsc;

// виклик методу з 6 аргументами
fAsc = IsAscending(1, 3, 5, 7, 9, 10); // fAsc = True

// виклик методу з 8 аргументами
int[] A = { 2, 3, 8, 8, 9, 10, 11, 23 };
fAsc = IsAscending(A); // fAsc = False

 

4. Як визначити кількість аргументів, що були передані в метод? Властивість Length

Кількість аргументів, що передаються в метод можна визначити з допомогою властивості Length.

Наприклад. Задано метод Average(), що визначає середнє арифметичне значення. У метод передається масив аргументів типу float з іменем vals. Кількість аргументів доступна у властивості

vals.Length

Код методу має наступний вигляд

float Average(params float[]vals)
{
  float avg = 0;

  // властивість vals.Length
  for (int i=0; i<vals.Length; i++)
  {
    avg += vals[i];
  }
  return (float)(avg / vals.Length);
}

Використання методу в іншому програмному коді може бути таким

float[] arguments = { 3.5f, 2.8f, 4.1f, 8.5f };
float avg;

avg = Average(arguments); // avg = 4.725

 

5. Які існують способи передачі змінної кількості аргументів в метод? Приклад

Змінну кількість аргументів можна передавати в метод двома способами:

  • коли при виклику методів аргументи розділені комою;
  • коли методу передається масив аргументів. Масив аргументів має ім’я.

Приклад. Нижче наведено два способи передачі аргументів в метод. Реалізується метод, що обчислює кількість додатніх елементів, які передаються в метод як параметри.

Реалізація методу наступна

int NPositives(params int[] numbers)
{
  int n = 0;
  for (int i = 0; i < numbers.Length; i++)
    if (numbers[i] >= 0) n++;
  return n;
}

Виклик методу з іншого програмного коду

// способи передачі аргументів у метод
int n;

// Спосіб 1 - передача через символ ','
n = NPositives(-3, 2, 8, 1, -5, -10, 100, 0); // n = 5
n = NPositives(); // n = 0
n = NPositives(-3, 1, 4); // n = 2

// Спосіб 2 - передача масивом
int[] A1 = { 8, 2, -3, -4, 5 };
int[] A2 = { -100, 0, -200, 500 };
int[] A3 = { };

n = NPositives(A1); // n = 3
n = NPositives(A2); // n = 2
n = NPositives(A3); // n = 0

 

6. Чи може послідовність аргументів, яка передається в метод і визначена модифікатором params, мати різні типи аргументів?

Ні не може. Для методів зі змінною кількістю аргументів діє наступне правило:

  • для кожного модифікатора params має бути послідовність значень-параметрів однакового типу. Цей тип задається в оголошенні методу як тип масиву параметрів.

Наприклад. Наступний код для методу NPositives() з п.5 буде неправильним:

n = NPositives(1, -5.75, 3, 0.5); // помилка, різні типи параметрів

 

7. Чи можна передавати в метод звичайні аргументи та аргументи змінної довжини одночасно?

Так можна. У цьому випадку першими мають слідувати звичайні аргументи. Після них мають слідувати аргументи змінної довжини з модифікатором params. Типи звичайних аргументів та аргументів змінної довжини можуть відрізнятись.

Наприклад. Нижче наведено реалізацію методу CalcNumber. Метод обчислює кількість входжень заданого цілочисельного параметру num в масиві параметрів numbers. Метод приймає два види аргументів:

  • звичайний аргумент – цілочисельний параметр num, кількість входжень якого потрібно обчислити;
  • масив аргументів numbers. Масив numbers оголошений з модифікатором params і може мати змінну кількість аргументів.

Реалізація методу CalcNumber() наступна:

// визначення кількості входжень числа num у масиві параметрів numbers
static int CalcNumber(int num, params int[] numbers)
{
  int n = 0;
  for (int i = 0; i < numbers.Length; i++)
    if (numbers[i] == num)
      n++;
  return n;
}

Демонстрація виклику методу з іншого програмного коду

int n;

// виклик методу
n = CalcNumber(5, -1, -3, 3, 5, 0, 2, 0, 8, 4, 5, 3, 4, 5, 20); // n = 3

 

8. Скільки модифікаторів params може мати метод, який приймає змінну кількість аргументів?

У методі, що приймає змінну кількість аргументів, може бути тільки один модифікатор params. У цьому випадку діє правило:

  • параметер з модифікатором params має бути останнім у списку формальних параметрів.

Отже, якщо у списку формальних параметрів задати два і більше модифікаторів params, то це правило виконуватись не буде – перед останнім модифікатором params будуть інші модифікатори. Це, в свою чергу, викличе помилку.

 

9. Яка помилка може виникнути, якщо в метод зі змінною кількістю аргументів передати пустий масив параметрів або викликати метод без параметрів?

У деяких методах, що приймають змінну кількість аргументів, потрібно робити перевірку на наявність хоча б одного аргументу. Це зв’язано з тим, що можна здійснити виклик методу без аргументів. У цьому випадку в метод буде передано пустий масив. Звертання до елементу пустого масиву призведе до помилки, і, як наслідок, буде згенеровано виключну ситуацію часу виконання.

 


Зв’язані теми