Общие сведения о типах записей в C#
Запись в C# — это класс или структуру, которая предоставляет специальный синтаксис и поведение для работы с моделями данных. Модификатор record
указывает компилятору синтезировать элементы, которые полезны для типов, основная роль которых хранит данные. Эти члены включают перегрузку ToString() и члены, поддерживающие равенство значений.
Когда следует использовать записи
Рекомендуется использовать запись вместо класса или структуры в следующих сценариях:
- Необходимо определить модель данных, зависящую от равенства значений.
- Необходимо определить тип, для которого объекты являются неизменяемыми.
Равенство значений
Для записей равенство значений означает, что две переменные типа "запись" равны, если совпадают типы и все значения свойств и полей. Для других ссылочных типов, таких как классы, равенство означает равенство ссылок. То есть две переменные типа "класс" равны, если они ссылаются на один и тот же объект. Методы и операторы, определяющие равенство двух экземпляров записи, используют равенство значений.
Не все модели данных хорошо работают с равенством значений. Например, Entity Framework Core использует ссылочное равенство, чтобы гарантировать использование только одного экземпляра типа сущности в том случае, когда разные объекты концептуально являются одной сущностью. По этой причине типы записей не подходят для использования в качестве типов сущностей в Entity Framework Core.
Неизменяемость
Неизменяемый тип — это тип, который не позволяет изменять значения свойств или полей объекта после его создания. Неизменность может быть полезной, если требуется обеспечить потокобезопасность типа или если существует зависимость от хэш-кода, остающегося неизменным в хэш-таблице. Записи предоставляют краткий синтаксис для создания неизменяемых типов и работы с ними.
Неизменяемость подходит не для всех сценариев данных. Entity Framework Core, например, не поддерживает обновление с неизменяемыми типами сущностей.
Как записи отличаются от классов и структур
Тот же синтаксис, который объявляет и создает экземпляры классов или структур, можно использовать с записями. Просто замените class
ключевое слово record
или используйте record struct
вместо struct
него. Аналогичным образом, тот же синтаксис для выражения связей наследования поддерживается классами записей. Записи отличаются от классов следующим образом.
- Для создания и создания экземпляра типа с неизменяемыми свойствами можно использовать позиционные параметры в основном конструкторе .
- Те же методы и операторы, которые указывают на равенство или неравенство ссылок в классах (например Object.Equals(Object) и
==
), указывают на равенство или неравенство значений в записях. - Можно использовать выражение
with
для создания копии неизменяемого объекта с новыми значениями в выбранных свойствах. - Метод записи
ToString
создает форматированную строку, содержащую имя типа объекта, а также имена и значения всех его открытых свойств. - Запись может наследовать от другой записи. Запись не может наследовать от класса, а класс не может наследовать от записи.
Структуры записей отличаются от структур, которые компилятор синтезирует методы для равенства и ToString
. Компилятор синтезирует Deconstruct
метод для структур позиционной записи.
Компилятор синтезирует открытое свойство только для инициализации для каждого основного параметра конструктора в объекте record class
. В компиляторе record struct
синтезируется общедоступное свойство чтения и записи. Компилятор не создает свойства для основных параметров class
конструктора и struct
типов, которые не включают record
модификатор.
Примеры
В следующем примере определяется открытая запись, которая использует позиционные параметры для объявления и создания экземпляра. Затем он выводит значения имени и свойства типа:
public record Person(string FirstName, string LastName);
public static class Program
{
public static void Main()
{
Person person = new("Nancy", "Davolio");
Console.WriteLine(person);
// output: Person { FirstName = Nancy, LastName = Davolio }
}
}
В следующем примере демонстрируется равенство значений в записях:
public record Person(string FirstName, string LastName, string[] PhoneNumbers);
public static class Program
{
public static void Main()
{
var phoneNumbers = new string[2];
Person person1 = new("Nancy", "Davolio", phoneNumbers);
Person person2 = new("Nancy", "Davolio", phoneNumbers);
Console.WriteLine(person1 == person2); // output: True
person1.PhoneNumbers[0] = "555-1234";
Console.WriteLine(person1 == person2); // output: True
Console.WriteLine(ReferenceEquals(person1, person2)); // output: False
}
}
В следующем примере показано использование выражения with
для копирования неизменяемого объекта и изменения одного из свойств:
public record Person(string FirstName, string LastName)
{
public required string[] PhoneNumbers { get; init; }
}
public class Program
{
public static void Main()
{
Person person1 = new("Nancy", "Davolio") { PhoneNumbers = new string[1] };
Console.WriteLine(person1);
// output: Person { FirstName = Nancy, LastName = Davolio, PhoneNumbers = System.String[] }
Person person2 = person1 with { FirstName = "John" };
Console.WriteLine(person2);
// output: Person { FirstName = John, LastName = Davolio, PhoneNumbers = System.String[] }
Console.WriteLine(person1 == person2); // output: False
person2 = person1 with { PhoneNumbers = new string[1] };
Console.WriteLine(person2);
// output: Person { FirstName = Nancy, LastName = Davolio, PhoneNumbers = System.String[] }
Console.WriteLine(person1 == person2); // output: False
person2 = person1 with { };
Console.WriteLine(person1 == person2); // output: True
}
}
Дополнительные сведения см. в разделе Записи (справочник по C#).
Спецификация языка C#
Дополнительные сведения см. в спецификации языка C#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по