TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #553 1.14K
День четыреста пятьдесят седьмой. #CSharp9
Позиционное и Номинальное Создание Объектов. Окончание
Фабричный Метод и Выражение 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/
More from @netdeveloperdiary
  1. Sep 27, 2026День 2797. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Окончание Начало Продол…
  2. Sep 26, 2026День 2796. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Продолжение Начало Три…
  3. Sep 25, 2026День 2795. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Начало Проблема с позиц…
  4. Sep 24, 2026День 2794. #Оффтоп #Здоровье Сегодня будет необычный пост. Завтра в Москве стартует конфер…
  5. Sep 23, 2026День 2793. #ЗаметкиНаПолях #SQL 10 Редких Возможностей SQL, Которые Стоит Знать Каждому. Ч…
  6. Sep 22, 2026День 2792. #ЗаметкиНаПолях #SQL 10 Редких Возможностей SQL, Которые Стоит Знать Каждому. Ч…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →