Переменное количество аргументов в методах. Модификатор params. Преимущества. Примеры методов с переменным количеством аргументов

Переменное количество аргументов в методах. Модификатор params. Преимущества. Примеры методов с переменным количеством аргументов


Содержание



1. Что означает переменное количество аргументов в методе? Ключевое слово params. Общая форма объявления метода с переменным количеством аргументов

Иногда бывают случаи, когда метод нужно вызвать несколько раз и каждый раз в этот метод нужно передавать разное количество аргументов. Такую ситуацию можно обойти создав перегруженные реализации метода.
Но не всегда можно знать сколько аргументов будет передаваться в метод, в особенности, если количество аргументов может быть довольно большим. В этом случае метод объявляется с переменным количеством аргументов.
Общая форма объявления метода с переменным количеством аргументов имеет вид:

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. Какая ошибка может возникнуть, если в метод с переменным количеством аргументов передать пустой массив параметров или вызвать метод без параметров?

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

 


Связанные темы