День четыреста пятьдесят шестой. #CSharp9
Позиционное и Номинальное Создание Объектов. Начало
C# позволяет создавать объекты, используя позиционный или номинальный стиль.
- Позиционное создание предполагает использование конструктора для задания значений свойствам:
- Номинальное создание предполагает использование инициализаторов:
См. также «Использование Неизменяемых Структур Данных в C#»
Номинальное Создание в C# 9
В C# 9 для создания неизменяемых типов предложен новый вид свойств только для инициализации с использованием ключевого слова
Источник: https://csharp.christiannagel.com/2020/04/21/c-9-positional-or-nominal-creation/
Позиционное и Номинальное Создание Объектов. Начало
C# позволяет создавать объекты, используя позиционный или номинальный стиль.
- Позиционное создание предполагает использование конструктора для задания значений свойствам:
public class Person {
public string FirstName { get; }
public string LastName { get; }
public Person(string firstName, string lastName) {
FirstName = firstName;
LastName = lastName;
}
}
Person p = new Person("Charles", "Leclerc");
При наследовании для инициализации унаследованных свойств конструктор может вызывать конструктор базового класса.- Номинальное создание предполагает использование инициализаторов:
Person p = new Person { FirstName = "Charles", LastName = "Leclerc" };
До сих пор проблема с инициализаторами была в том, что таким образом можно было задавать значения только доступным для записи свойствам. Инициализатор объекта - это просто синтаксический сахар. За кулисами он устанавливает значения свойствам после вызова конструктора. Таким способом невозможно создать неизменяемые типы. Поэтому часто приходится создавать конструкторы и использовать позиционный стиль. См. также «Использование Неизменяемых Структур Данных в C#»
Номинальное Создание в C# 9
В C# 9 для создания неизменяемых типов предложен новый вид свойств только для инициализации с использованием ключевого слова
init. Эти свойства могут быть установлены после выполнения конструктора, используя инициализатор объекта:public class Person {
public string FirstName { get; init; }
public string LastName { get; init; }
}
Person p = new Person { FirstName = "Charles", LastName = "Leclerc" };
Свойства только для инициализации могут быть установлены в момент создания объекта, но становятся доступными только для чтения после завершения создания объекта. Когда требуется проверка при задании свойства, ключевое слово init может использоваться для определения блока проверки, так же как get и set. Кроме того, иногда может требоваться более сложная проверка, затрагивающая комбинацию нескольких свойств. В таком случае можно использовать новый валидатор с блоком кода, обозначенным ключевым словом init:public class Person {
public string FirstName { get; init; }
public string LastName { get; init; }
init {
if (FirstName.Length + LastName.Length > 52)
throw new Exception("…");
}
}
Окончание следует…Источник: https://csharp.christiannagel.com/2020/04/21/c-9-positional-or-nominal-creation/
👍1
День четыреста пятьдесят седьмой. #CSharp9
Позиционное и Номинальное Создание Объектов. Окончание
Фабричный Метод и Выражение With
Для создания новых объектов из существующих предложено использовать конструкторы копий и фабричный метод или выражение
Вместо определения конструктора копии и метода
Позиционное и Номинальное Создание Объектов. Окончание
Фабричный Метод и Выражение With
Для создания новых объектов из существующих предложено использовать конструкторы копий и фабричный метод или выражение
With. В следующем фрагменте кода класс Person определяет конструктор копии, который возвращает новый объект Person. Метод With помечается как фабричный и вызывает конструктор копии. В классе Racer, производном от Person, определяется конструктор копии, который, в свою очередь, вызывает конструктор копии базового класса. Также переопределяется метод With базового класса для возврата объекта Racer. public class Person {
public string FirstName { get; init; }
public string LastName { get; init; }
protected Person(Person p) =>
(FirstName, LastName) = (p.FirstName, p.LastName);
[Factory] public virtual Person With() =>
new Person(this);
}
public class Racer : Person {
public string RacingTeam { get; init; }
protected Racer(Racer r) : base(r) =>
RacingTeam = r.RacingTeam;
[Factory] public override Racer With() =>
new Racer(this);
}
Таким образом, можно создавать новые экземпляры со свойствами только для чтения. А поскольку метод With является фабричным, инициализатор объекта может быть использован для внесения некоторых изменений:Person p1 = new Racer { FirstName = "Charles", LastName = "Leclerc", RacingTeam = "Ferrari" };
Person p2 = p1.With() { FirstName = "Arthur" };
Кроме того, предложено использовать выражение with вместо вызова фабричного метода:Person p3 = p1 with { FirstName = "Arthur" };
ЗаписиВместо определения конструктора копии и метода
With также предлагается объявлять новый тип объектов – записи, используя ключевое слово record. В этом типе объектов будет автоматически создан конструктор копии, метод With, методы проверки на равенство и т.п.:public record class Person {
public string FirstName { get; init; }
public string LastName { get; init; }
}
public record class Racer : Person {
public string RacingTeam { get; init; }
}
Person p1 = new Racer { FirstName = "Charles", LastName = "Leclerc", RacingTeam = "Ferrari" };
Person p2 = p1 with { FirstName = "Arthur" };
Источник: https://csharp.christiannagel.com/2020/04/21/c-9-positional-or-nominal-creation/