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);
Инициализация полей по умолчанию
Иногда хочется задать значения по умолчанию для некоторых полей, если не все параметры поступают в конструктор. Например, если e-mail не обязателен:
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();
}
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ