C# 12 - Первичные конструкторы
Начиная с C# 12, можно объявлять первичный конструктор внутри классов и структур. Параметры размещаются в скобках сразу после имени типа. Они имеют широкую область видимости: могут инициализировать свойства или поля, использоваться как переменные в методах и локальных функциях, а также передаваться в базовый конструктор.
Начиная с C# 12, можно объявлять первичный конструктор внутри классов и структур. Параметры размещаются в скобках сразу после имени типа.
public class Car(string make)
{
public string Make => make;
}
Параметры первичного конструктора имеют широкую область видимости. Их можно использовать для инициализации свойств или полей, в качестве переменных в методах и локальных функциях, а также передавать в базовый конструктор.
Использование первичного конструктора означает, что эти параметры необходимы для любого экземпляра типа. Если присутствует явно объявленный конструктор, он должен использовать синтаксис инициализатора this(...) для вызова первичного конструктора. Это гарантирует, что все конструкторы фактически присваивают значения параметрам первичного конструктора.
В классах, включая типы record class, неявный конструктор без параметров не создаётся при наличии первичного конструктора. В структурах же, включая типы record struct, неявный конструктор без параметров создаётся всегда и инициализирует все поля, включая параметры первичного конструктора, нулевым битовым шаблоном. Если вы решите включить явный конструктор без параметров, он должен вызвать первичный конструктор, что позволяет передать иные значения для параметров первичного конструктора.
В следующем коде показаны примеры первичных конструкторов:
public class ElectricCar(string make, int batteryCapacity) : Car(make)
{
public ElectricCar() : this("unknown", 0)
{
}
public int BatteryCapacity => batteryCapacity;
}
Внутри типов class и struct параметры первичного конструктора доступны на протяжении всего тела типа. Их можно использовать как поля-члены. При использовании компилятор автоматически захватывает параметр конструктора в приватное поле с именем, сгенерированным компилятором. Однако если параметр первичного конструктора нигде в теле типа не используется, приватное поле не создаётся. Это превентивное правило не позволяет случайно выделить две копии параметра первичного конструктора при его передаче в базовый конструктор.
Если тип помечен модификатором record, компилятор поступает иначе: он синтезирует публичное свойство с тем же именем, что и параметр первичного конструктора. Для типов record class, если параметр первичного конструктора совпадает по имени с базовым первичным конструктором, это свойство становится публичным свойством базового типа record class и не дублируется в производном типе record class. Важно отметить, что для не record-типов такие свойства не создаются.
Comments
Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.