JavaRush /Курси /C# SELF /Значення за замовчуванням та іменовані аргументи

Значення за замовчуванням та іменовані аргументи

C# SELF
Рівень 8 , Лекція 4
Відкрита

1. Значення за замовчуванням для параметрів

Уявіть собі кавʼярню: якщо ви не уточните, чи потрібен цукор у каві, бариста за замовчуванням додасть одну ложку. Але іноді ви захочете… дві! Або взагалі без цукру. Так само і з методами: інколи зручно, щоб окремі параметри мали стандартні значення, якщо їх явно не вказано.

А іменовані аргументи — це як можливість у замовленні кави зазначити: «А молоко мені соєве, а не звичайне», незалежно від того, в якому порядку зазвичай подають інгредієнти.

У C# обидва ці механізми роблять ваш код чистішим і зручнішим та допомагають уникати помилок. Вони часто трапляються в реальних проєктах — від бібліотек .NET до популярних фреймворків, тож роботодавці цінують, коли ви впевнено ними користуєтеся.

Синтаксис

Значення за замовчуванням для параметра методу задається прямо в оголошенні через знак =. Якщо під час виклику методу цей параметр не вказано, використовується зазначене значення за замовчуванням.


void PrintStudent(string name, int age = 18)
{
    Console.WriteLine($"Студент: {name}, вік: {age}");
}
Значення за замовчуванням для параметра age

Як це працює?

  • Якщо викликати PrintStudent("Аліса"); — буде виведено: Студент: Аліса, вік: 18.
  • Якщо викликати PrintStudent("Саша", 22); — буде виведено: Студент: Саша, вік: 22.

Для яких типів це працює?

Значення за замовчуванням можна задати для будь-якого типу параметра, але є нюанси:

  • Для посилальних типів (string, класи тощо): можна вказати null або конкретний літерал.
  • Для типів значення (int, double, bool тощо): задається літерал потрібного типу.
  • Для перелічень (enum) та структур також можна використовувати значення за замовчуванням.

void AddStudent(string name, int course = 1, double averageScore = 5.0, string comment = null)
{
    Console.WriteLine($"Додано студента: {name}, курс: {course}, середній бал: {averageScore}, коментар: {comment}");
}
Кілька параметрів з різними значеннями за замовчуванням

Приклади виклику:

  • AddStudent("Іван");
  • AddStudent("Марія", 2);
  • AddStudent("Федір", 2, 4.7, "З відзнакою");

Порядок параметрів зі значеннями

Усі необовʼязкові параметри (зі значенням за замовчуванням) мають іти праворуч (після всіх обовʼязкових). Якщо ви спробуєте поставити параметр зі значенням за замовчуванням перед обовʼязковим, компілятор повідомить про помилку.


// Помилка!
void Test(int a = 1, int b)
{
    // ...
}
Параметр зі значенням за замовчуванням не може йти перед обовʼязковим

Чому так? Інакше компілятор не зможе коректно зіставити аргументи з параметрами під час виклику методу.

2. Іменовані аргументи

Зазвичай, коли ви викликаєте метод і передаєте аргументи, їхній порядок має відповідати порядку параметрів у визначенні методу. Але іноді список довгий, деякі параметри мають значення за замовчуванням, і помилитися легко.

Іменовані аргументи дозволяють явно вказати, якому параметру ви передаєте який аргумент, у будь-якому порядку.


AddStudent(name: "Єлизавета", averageScore: 4.2, comment: "Найкращий студент семестру");
Виклик методу з іменованими аргументами
  • Тут ми не вказуємо курс (course), отже він буде 1 (за замовчуванням).
  • Не потрібно памʼятати, яким за рахунком був параметр comment — достатньо вказати його імʼя.

Ви навіть можете поміняти місцями параметри:


AddStudent(averageScore: 3.7, name: "Георгій");
Порядок іменованих аргументів не має значення

Це зручно, та код стає значно читабельнішим!

Використання з позиційними аргументами

Іменовані та позиційні аргументи (без імені) можна поєднувати, але всі позиційні мають іти перед іменованими.


// Правильно
AddStudent("Сергій", averageScore: 4.9);

// Помилка
AddStudent(course: 2, "Філіп");
Після першого іменованого параметра всі інші мають бути лише іменованими

Після першого іменованого параметра все інше має бути лише іменованим. Компілятор суворо стежить за цим порядком, щоб уберегти вас від несподіванок.

Зручно для методів з багатьма параметрами

Це частий прийом для методів, у яких є багато додаткових параметрів. Наприклад, якби ви писали метод для додавання користувача до хмарної бази даних:


void RegisterUser(
    string username,
    string password,
    string email = null,
    bool admin = false,
    bool sendWelcomeEmail = true,
    string language = "uk"
)
Метод з багатьма параметрами та значеннями за замовчуванням

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

RegisterUser("cat", "qwerty", null, false, true, "uk");

З іменованими аргументами усе читабельно та надійно:

RegisterUser("cat", "qwerty", admin: true, sendWelcomeEmail: false, language: "en");

Порада: використовуйте іменовані аргументи — код читатиметься навіть без документації!

3. Особливості реалізації та часті помилки

На початку роботи зі значеннями за замовчуванням та іменованими аргументами легко припуститися помилок.

  • Порядок параметрів. Завжди розташовуйте параметри зі значеннями за замовчуванням після обовʼязкових. Якщо поміняти місцями — компілятор видасть помилку.
  • Зміна значення за замовчуванням у бібліотеці. Якщо ви зміните значення за замовчуванням у бібліотеці, наявні клієнти автоматично його не підхоплять. Значення за замовчуванням підставляється під час компіляції у викликаючий код. Тож добре зважуйте такі зміни у публічних бібліотеках.
  • Поєднання позиційних та іменованих аргументів. Якщо ви поєднали позиційні та іменовані, але після іменованого знову намагаєтеся вказати позиційний — це не спрацює. Наприклад: Func(a: 1, 2) — буде помилка.
  • Помилка в імені параметра. Компілятор тут суворий: якщо ви переплутали літери (наприклад, написали naem: "Міша"), отримаєте повідомлення на кшталт: «Немає такого параметра».
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ