1. Прості конструктори
Конструктор — це спеціальний метод класу, який викликається автоматично під час створення об’єкта. Він ініціалізує (налаштовує) об’єкт: встановлює початкові значення, виконує перевірки — може навіть підняти вам настрій, якщо додасте в нього жарт.
Конструктор дає змогу відразу створювати об’єкт у певному стані, а не встановлювати всі його дані окремо через поля та властивості вручну. Це зручно й безпечно, адже ви одразу вказуєте усі важливі параметри — і не забудете щось критично важливе.
Без конструктора код може виглядати громіздким і бути схильним до помилок:
Person p = new Person();
p.Name = "Юля";
p.Age = 25; // А що, як забудемо вказати вік?
З конструктором:
Person p = new Person("Юля", 25); // Усе передано відразу, і об’єкт готовий до роботи!
Синтаксис конструктора
Конструктор — це спеціальний «метод», імʼя якого повністю збігається з імʼям класу й який не має типу повернення (навіть void). Ось так виглядає конструктор за замовчуванням:
public class Person
{
// Конструктор за замовчуванням (без параметрів)
public Person()
{
// Тут можна написати код ініціалізації
}
}
Конструктор за замовчуванням — це такий невидимий «помічник», який не приймає жодних параметрів і просто ініціалізує всі поля та властивості вашого класу їхніми значеннями за замовчуванням:
- Для числових типів (int, double, float тощо) це буде 0.
- Для логічного типу (bool) це false.
- Для посилальних типів (string, інші класи) це null (що означає «нічого», «відсутність посилання на об’єкт»).
- Для DateTime це буде 01.01.0001 00:00:00.
Як викликати конструктор?
Власне, коли ви використовуєте оператор new під час створення об’єкта, ви викликаєте конструктор!
Person p = new Person();
Якщо ви явно не визначаєте жодного конструктора, компілятор C# створить для вас конструктор за замовчуванням (без параметрів). Але якщо оголосите хоча б один власний — конструктор за замовчуванням зникне, і компілятор попросить вас додати його вручну, якщо він потрібен.
Приклад
Додаймо конструктор до класу нашого застосунку. Ось проста версія класу студента:
public class Student
{
public string Name;
public int Age;
// Конструктор з двома параметрами (імʼя й вік)
public Student(string name, int age)
{
Name = name; // Присвоюємо значення поля
Age = age;
}
}
Тепер можна створити студента так:
Student s = new Student("Іван", 21);
Console.WriteLine($"{s.Name}: {s.Age} років"); // Іван: 21 рік
- Ми оголосили конструктор тієї ж видимості (public), що й сам клас.
- У конструкторі присвоюємо значення полям, використовуючи передані параметри.
- Такий підхід захищає від забудькуватості: компілятор змусить вас указувати імʼя й вік під час створення об’єкта.
2. Параметри конструктора
У C# можна оголосити кілька конструкторів із різними наборами параметрів. Це називається перевантаженням конструктора (про перевантаження методів поговоримо згодом).
Наприклад, додаймо конструктор без параметрів:
public class Student
{
public string Name;
public int Age;
// Конструктор за замовчуванням
public Student()
{
Name = "Безіменний";
Age = 0;
}
// Конструктор з параметрами
public Student(string name, int age)
{
Name = name;
Age = age;
}
}
Тепер обидва варіанти можливі:
Student s1 = new Student(); // Імʼя: Безіменний, вік: 0
Student s2 = new Student("Оля", 22); // Імʼя: Оля, вік: 22
Використання конструктора для валідації
Конструктор — чудове місце, щоб перевіряти «якість» вхідних даних. Наприклад, студент не може мати відʼємний вік!
public Student(string name, int age)
{
if (age < 0)
throw new ArgumentException("Вік не може бути відʼємним!");
Name = name;
Age = age;
}
Тепер, якщо хтось спробує створити студента Student("Малюк", -2), застосунок викине виняток (ArgumentException). Такий підхід часто використовують для «залізобетонної» надійності даних.
3. Ініціалізація складних об’єктів
Часто в реальних застосунках один об’єкт може не лише складатися з примітивів, а й містити інші об’єкти:
public class Group
{
public string GroupName;
public Student[] Students;
public Group(string groupName, Student[] students)
{
GroupName = groupName;
Students = students;
}
}
Тепер можна легко створити групу з набором студентів:
var students = new Student[]
{
new Student("Іван", 20),
new Student("Марія", 19)
};
Group g = new Group("Група-101", students);
Ініціалізація полів за замовчуванням
Іноді варто задати значення за замовчуванням для деяких полів, якщо не всі параметри надходять у конструктор. Наприклад, якщо електронна адреса не обов’язкова:
public Student(string name, int age)
{
Name = name;
Age = age;
Email = "unknown@noemail.com"; // Значення за замовчуванням
}
4. Ініціалізація через Object Initializer
З конструкторами можна поєднувати інший зручний синтаксис — ініціалізатори об’єктів. Ви можете викликати конструктор, а потім у фігурних дужках перелічити значення властивостей нового об’єкта:
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
// Конструктор усе одно рекомендується
public Student(string name, int age)
{
Name = name;
Age = age;
Email = "";
}
}
Student s = new Student("Антон", 18) { Email = "anton@domain.com" }; // конструктор + властивості
Цей синтаксис чудово поєднується з наявністю конструктора, коли частина параметрів має значення за замовчуванням або вони не завжди відомі під час створення.
5. Типові помилки та особливості
Працюючи з конструкторами, новачки стикаються з кількома поширеними помилками. Розгляньмо їх на простих прикладах:
Помилка № 1: Незбіг імен
Іноді плутають імена параметрів і полів, особливо якщо вони відрізняються лише регістром.
public Student(string Name, int Age) // З великої літери!
{
Name = Name; // Ой! Обидва Name посилаються на параметр. Поле залишиться неініціалізованим.
}
Як правильно: Використовувати this для посилання на поле об’єкта:
public Student(string name, int age)
{
this.Name = name;
this.Age = age;
}
Або просто обирати різні імена (наприклад, nameParam, ageParam), але практика з this. вважається гарним стилем, особливо коли йдеться про великі проєкти.
Помилка № 2: Немає конструктора за замовчуванням
Якщо ви оголосили хоча б один конструктор, а потім намагаєтеся створити об’єкт без параметрів — отримаєте помилку компіляції:
public class Student
{
public Student(string name) { /*...*/ }
}
// десь у коді
Student s = new Student(); // Помилка! Немає конструктора без параметрів.
Рішення: Явно додайте конструктор без параметрів:
public Student() { /*...*/ }
Помилка № 3: Нескінченна рекурсія — якщо конструктор викликає сам себе
public Student()
{
// Помилка! Викликає сам себе — нескінченна рекурсія.
new Student();
}
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ