Необов’язкові аргументи. Переваги. Приклади застосування необов’язкових аргументів. Неоднозначність в необов’язкових аргументах

Необов’язкові аргументи. Переваги. Приклади застосування необов’язкових аргументів. Неоднозначність в необов’язкових аргументах


Зміст



1. Що являють собою необов’язкові аргументи та необов’язкові параметри?

В оголошенні методу частина його параметрів може отримувати значення за замовчуванням. Параметр, що отримує значення за замовчуванням, називається необов’язковий параметр. Метод, що в оголошенні містить необов’язкові параметри, може викликатись без задавання аргументів, що відповідають цим параметрам. Аргументи, що передаються в метод і відповідають необов’язковим параметрам, називаються необов’язковими аргументами.

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

Загальна форма задавання необов’язкового аргументу в переліку параметрів методу має вигляд:

type parametr_name = const_value

де

  • type – тип необов’язкового параметру;
  • parameter_name – ім’я параметру, що відповідає необов’язковому аргументу при виклику метода;
  • const_value – константне значення за замовчуванням, що присвоюється необов’язковому параметру.

Загальна форма методу, що містить один необов’язковий параметр, має вигляд:

access return_type MethodName(type parameter_name = const_value)
{
  // ...
}

де

  • access – модифікатор доступу до методу (private, protected, public);
  • return_type – тип, що повертає метод;
  • MethodName – ім’я методу;
  • parameter_name – ім’я параметру, що відповідає аргументу за замовчуванням;
  • const_value – значення за замовчуванням, що присвоюється параметру з іменем parameter_name у випадку, якщо викликати метод MethodName() без параметрів.

Після такого оголошення, виклик методу MethodName() можна здійснювати двома способами:

  • з задаванням явно заданого аргументу;
  • без задавання аргументу (з пустими параметрами). У цьому випадку, параметру parameter_name буде присвоєне значення за замовчування value.

 

2. Переваги застосування необов’язкових аргументів

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

  • не потрібно вводити додаткові “перевантажені” реалізації методу;
  • спрощується виклик складних методів чи конструкторів класу. Аргументи, що не вказуються при виклику такого методу, отримують значення за замовчуванням.

 

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

Приклад 1. Метод, що визначає об’єм кулі. Метод отримує один вхідний параметр (радіус кулі), який є необов’язковим аргументом.

// метод, що містить необов'язковий аргумент 
double SphereVolume(double radius = 1.0)
{
  return 4.0 / 3.0 * 3.1415 * radius * radius * radius;
}

Після такого оголошення, метод можна викликати двома способами:

  • без явно заданого аргументу;
  • з явно заданим аргументом.

Нижченаведений програмний код демонструє виклик методу різними способами

// Продемонструвати виклик методу SphereVolume
double vol;

// виклик методу без явно заданого (необов'язкового) аргументу
vol = SphereVolume(); // vol = 4.188667

// виклик методу з явно заданим аргументом
vol = SphereVolume(3.0); // vol = 113.094

Як видно з вищенаведеного коду, перший раз метод SphereVolume() викликається без явно заданого аргументу. У цьому випадку, в метод нічого не передається, а внутрішній параметр radius отримує значення за замовчуванням -1.0, що було задане при оголошенні методу.
Другий раз відбувається виклик методу

vol = SphereVolume(3.0);

У цьому випадку, в метод передається явно заданий аргумент 3.0. Формальний параметр методу radius отримує значення аргументу рівне 3.0. Значення за замовчуванням затирається новим значенням.

Приклад 2. Реалізація методу, що отримує чотири необов’язкові параметри.

Метод може отримувати будь-яку кількість необов’язкових параметрів.
Нижче наведено реалізацію методу LengthLine(), що визначає довжину відрізку. Метод отримує координати точок:

  • x1, y1 – координати першої точки відрізку;
  • x2, y2 – координати другої точки відрізку.
// метод визначає довжину відрізка
static float LineSegment(float x1 = 0, float y1 = 0, float x2 = 1, float y2 = 1)
{
  float length;
  length = (float)Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
  return length;
}

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

// Продемонструвати виклик методу LineSegment
float len;

// виклик методу без явно заданих аргументів
// аргументи x1, y1, x2, y2 - необов'язкові
len = LineSegment(); // x1=0, y1=0, x2=1, y2=1; len = 1.414214

// виклик методу з 1 явно заданим аргументом
// аргумент x1, y1, x2 - необов'язкові
len = LineSegment(3); // x1=3, y1=0, x2=1, y2=1; len = 2.236068

// виклик методу з 2 явно заданими аргументами
// аргументи x2, y2 - необов'язкові
len = LineSegment(-1, 4); // x1=-1, y1=4, x2=1, y2=1; len = 3.605551

 

4. Приклади реалізації та використання класів, що містять конструктори з необов’язковими аргументами

Приклад 1. Задано клас Triangle, що реалізує трикутник на площині.
У класі реалізовано:

  • шість загальнодоступних змінних з іменами x1, y1, x2, y2, x3, y3. Це є координати точок, що утворюють трикутник;
  • конструктор, що отримує необов’язкові аргументи.

Лістинг класу Triangle наступний:

// клас, що реалізує трикутник
class Triangle
{
  // координати точок, що утворюють трикутник
  public double x1, y1, x2, y2, x3, y3;

  // конструктор класу, отримує необов'язкові аргументи
  public Triangle(double x1 = 0, double y1 = 0, double x2 = 1, double y2 = 1, double x3 = -1, double y3 = -1)
  {
    // ініціалізація змінних класу
    this.x1 = x1; this.y1 = y1;
    this.x2 = x2; this.y2 = y2;
    this.x3 = x3; this.y3 = y3;
  }
}

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

// Демонстрація використання необов'язкових аргументів в конструкторі класу Triangle
// 1. Передати усі аргументи явним чином в конструктор класу
Triangle tr1 = new Triangle(2, 3, -1, -3, 0, 5); // x1=2, y1=3, x2=-1, y2=-3, x3=0, y3=5

// 2. Передати 5 аргументів явним чином, аргумент y3 - необов'язковий аргумент
Triangle tr2 = new Triangle(1, 2, 0, 0, -4); // x1=1, y1=2, x2=0, y2=0, x3=-4, y3=-1

// 3. Передати 2 аргументи явним чином, аргументи x2, y2, x3, y3 - необов'язкові
Triangle tr3 = new Triangle(8, 9); // x1=8, y1=9, x2=1, y2=1, x3=-1, y3=-1

При створенні об’єкту класу Triangle викликається конструктор, що містить параметри за замовчуванням. У першому випадку створюється об’єкт tr1. При створенні об’єкту викликається конструктор, якому передаються усі 6 явно заданих аргументів (обов’язкових аргументів).
У другому випадку, при створенні об’єкту tr2 викликається конструктор, в якому 5 аргументів задаються явно і один (y3) є необов’язковим аргументом. У методі необов’язковому аргументу y3 присвоюється значення за замовчуванням -1.
У третьому випадку створюється об’єкт з іменем tr3. При створенні цього об’єкту конструктор отримує значення двох явно заданих аргументів, значення яких присвоюються параметрам-змінним x1, y1. Інші 4 параметри конструктора отримують значення за замовчуванням, у даному випадку x2=1, y2=1, x3=-1, y3=-1.

Приклад 2. Нехай задано клас ArrayInt, що реалізує масив цілих чисел. У класі оголошується конструктор, що містить необов’язкові аргументи.

class ArrayInt
{
  int[] A;

  // конструктор з необов'язковим аргументом n
  public ArrayInt(int n = 0)
  {
    A = null;
    if (n == 0) return;

    // виділити пам'ять під масив A
    A = new int[n];

    // занулити масив
    for (int i = 0; i < A.Length; i++)
      A[i] = 0;
  }

  // методи доступу до масиву
  public int[] Get() { return A; }

  public void Set(int[] AA)
  {
    A = new int[AA.Length];

    for (int i = 0; i < A.Length; i++)
      A[i] = AA[i];
  }
}

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

// виклик конструкторів з необов'язковими аргументами
ArrayInt ai1 = new ArrayInt(); // виклик конструктора з вказанням необов'язкового аргументу
ArrayInt ai2 = new ArrayInt(5); // виклик конструкторам з обов'язковим аргументом

// перевірка
int n_items;

if (ai1.Get() != null)
  n_items = ai1.Get().Length;
else
  n_items = 0; // n_items = 0

n_items = ai2.Get().Length;

 

5. Які вимоги накладаються синтаксисом C# на порядок оголошення необов’язкових аргументів у методі?

Згідно синтаксису C#, при використанні в методі необов’язкових аргументів потрібно дотримуватись наступного правила:

  • оголошення необов’язкових параметрів повинно бути реалізоване справа від обов’язкових.

 

6. Скільки необов’язкових параметрів може бути оголошено в методі?

У методі може бути оголошено будь-яка кількість необов’язкових параметрів. Головне, щоб їх оголошення слідувало справа від оголошення обов’язкових параметрів.

 

7. В яких елементах мови програмування C# можна використовувати необов’язкові аргументи?

Необов’язкові аргументи можна використовувати в:

  • методах класів (в т.ч. і конструкторах);
  • конструкторах класів;
  • делегатах.

 

8. Приклад використання необов’язкових аргументів у делегатах

Делегати так само як і методи можуть приймати необов’язкові аргументи. У цьому випадку синтаксис оголошення делегату такий самий як і синтаксис оголошення методу.

Нехай задано делегат TInt, що отримує та повертає цілочисельне значення. Для параметру делегату задається значення за замовчуванням, яке рівне 1. Також задаються 3 методи, сигнатура яких співпадає з сигнатурою делегату.

// оголошення типу делегата TInt, що отримує значення за замовчуванням = 1
delegate int TInt(int d = 1);

// метод, що множить ціле число на 2
static int Mult2(int d)
{
  return d * 2;
}

// метод, що підносить ціле число до квадрату
static int Square(int d)
{
  return d * d;
}

// метод, що множить число на 5
static int Mult5(int d)
{
  return d * 5;
}

Використання делегату типу TInt, що отримує необов’язковий аргумент може бути таким:

TInt t; // оголосити делегат типу TInt

// створити ланцюг викликів методів
t = Mult2; // t => Mult2
t += Mult5; // t => Mult2 => Mult5

// викликати послідовно методи
int result;

// виклик методів Mult2(), Mult5() з необов'язковим аргументом 
result = t(); // result = 5

// виклик методів Mult2(3), Mult5(3) з явно заданим аргументом
result = t(3); // result = 15

 

9. Що означає термін “неоднозначність” при виклику необов’язкових аргументів? Приклад

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

Наприклад. Нехай задано два “перевантажені” методи Sum(), що отримують необов’язкові аргументи. В обох методах перший аргумент з іменем a є обов’язковим.

int Sum(int a, int b = 1, int c = 2)
{
  return a+b+c;
}

int Sum(int a, double b = 2.0, double c = 3.0)
{
  return (int)(a + b + c);
}

Якщо написати наступний код виклику методу Sum()

int t;

// неоднозначний виклик, компілятор не знає який метод викликати
t = Sum(5);

то компілятор видасть повідомлення про помилку:

The call is ambiguous between the following methods or properties:
'Sum(int, int, int)' and 'Sum(int, double, double)'

що означає

Виклик є невизначеним для наступних методів
Sum(int, int, int) та Sum(int, double, double)

 


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