Выражения with для записей
Создавайте изменённые копии неизменяемых объектов.
«Выражения with для записей» — бесплатный урок C# Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 4 уроков всего.
Выражение копирования
Выражение with создаёт копию записи с изменёнными свойствами, оставляя исходную запись без изменений. Это идиоматический способ «обновлять» неизменяемые записи.
using System;
record Point(int X, int Y);
var a = new Point(1, 2);
var b = a with { Y = 9 };
Console.WriteLine(a + " | " + b); // Point { X = 1, Y = 2 } | Point { X = 1, Y = 9 }Неразрушающее изменение
Исходная запись никогда не изменяется. with выполняет поверхностное копирование и применяет перечисленные изменения только к копии.
using System;
record User(string Name, int Age);
var original = new User("Ada", 30);
var older = original with { Age = 31 };
Console.WriteLine(original.Age + " " + older.Age); // 30 31Изменение нескольких свойств
Перечислите несколько присваиваний внутри фигурных скобок, чтобы изменить сразу несколько свойств.
using System;
record Config(string Env, int Retries, bool Verbose);
var baseCfg = new Config("dev", 3, false);
var prod = baseCfg with { Env = "prod", Verbose = true };
Console.WriteLine(prod.Env + " " + prod.Retries + " " + prod.Verbose); // prod 3 TrueКопирование неизменённых свойств
Свойства, которые Вы не указали, копируются без изменений из исходной записи.
using System;
record Product(string Name, decimal Price, int Stock);
var p = new Product("Book", 12m, 5);
var discounted = p with { Price = 10m };
Console.WriteLine(discounted.Name + " " + discounted.Stock); // Book 5Оператор with и равенство значений
Поскольку записи используют равенство значений, копия, в которой ничего не изменено, равна оригиналу.
using System;
record Coord(int X, int Y);
var a = new Coord(1, 2);
var b = a with { };
Console.WriteLine(a == b); // True (value equal)
Console.WriteLine(ReferenceEquals(a, b)); // False (different objects)Семантика поверхностного копирования
with копирует ссылки, а не глубокие графы объектов. Вложенный изменяемый объект является общим для оригинала и копии.
using System;
using System.Collections.Generic;
record Cart(List<string> Items);
var a = new Cart(new List<string> { "x" });
var b = a with { };
b.Items.Add("y"); // shared list!
Console.WriteLine(a.Items.Count); // 2Оператор with для структур-записей
Структуры-записи также поддерживают with, создавая изменённую копию типа значения.
using System;
record struct Size(int W, int H);
var s = new Size(4, 4);
var wide = s with { W = 8 };
Console.WriteLine(wide.W + "x" + wide.H); // 8x4Цепочки выражений with
Вы можете объединять выражения with в цепочку, применяя последовательность изменений, каждое из которых создаёт новую запись.
using System;
record Point(int X, int Y, int Z);
var p = new Point(0, 0, 0)
with { X = 1 }
with { Y = 2 }
with { Z = 3 };
Console.WriteLine(p); // Point { X = 1, Y = 2, Z = 3 }Обновления без строителей
with избавляет от необходимости создавать классы-строители: просто скопируйте запись и измените нужные поля.
using System;
record Email(string To, string Subject, string Body);
var draft = new Email("a@b.com", "Hi", "");
var ready = draft with { Body = "Welcome!" };
Console.WriteLine(ready.Body); // Welcome!Пользовательская логика копирования
Записи создают защищённый конструктор копирования, который использует with. Вы можете объявить собственный конструктор, чтобы настроить процесс копирования.
using System;
record Audited(string Name) {
public int Version { get; init; } = 1;
protected Audited(Audited other) {
Name = other.Name;
Version = other.Version + 1; // bump on every copy
}
}
var a = new Audited("x");
var b = a with { };
Console.WriteLine(a.Version + " " + b.Version); // 1 2Объединение всех элементов
Моделирование переходов состояний с помощью with обеспечивает удобную для аудита неизменяемую историю.
using System;
record Order(string Id, string Status);
var created = new Order("O1", "Created");
var paid = created with { Status = "Paid" };
var shipped = paid with { Status = "Shipped" };
Console.WriteLine(created.Status + " -> " + paid.Status + " -> " + shipped.Status);Быстрая проверка
Проверьте, насколько хорошо Вы понимаете выражения with.
Повторение
Вы изучили выражения with для записей.
a with { Prop = value }копирует и изменяет выбранные свойства.- Оригинал никогда не изменяется: операция является неразрушающей.
- Копия является поверхностной, поэтому вложенные изменяемые объекты остаются общими.
- Это работает с записями и структурами-записями; выражения можно объединять в цепочку.
Часто задаваемые вопросы
Урок «Выражения with для записей» бесплатный?
Да — полный текст урока «Выражения with для записей» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 4 уроков всего.
Чему я научусь в уроке «Выражения with для записей»?
Создавайте изменённые копии неизменяемых объектов. Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C# Academy?
Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Выражения with для записей»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C# Academy?
Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Сеттеры только для init
- Модификатор required
- Шаблоны неизменяемых объектов
- Выражения with для записей