【转】[C#] Record 的使用
转自:https://doubao.com/chat
在 C# 9.0 及以后的版本中,
record是一种特殊的引用类型,它提供了简洁的语法来创建不可变的数据模型。以下是关于 C# record的详细介绍:1. 基本概念
record是一种引用类型,但在很多方面表现得像值类型:
- 不可变性:默认情况下,
record的属性是只读的(通过init访问器)。 - 值语义:比较两个
record实例时,比较的是它们的属性值,而非引用。 - 不可变性:默认情况下,
record的属性是只读的(通过init访问器)。 - 值语义:比较两个
record实例时,比较的是它们的属性值,而非引用。 - 内置方法:自动生成
ToString()、Equals()、GetHashCode()和解构方法。 - 内置方法:自动生成
ToString()、Equals()、GetHashCode()和解构方法。
2. 声明语法
2.1 位置记录(Positional Record)
使用参数列表声明属性:
public record Person(string FirstName, string LastName);
相当于隐式定义了:
public string FirstName { get; init; }
public string LastName { get; init; }
2.2 传统语法
public record Person
{
public string FirstName { get; init; }
public string LastName { get; init; }
};
3. 不可变性与初始化
record的属性默认是只读的,只能在初始化时设置值:
var person = new Person("John", "Doe");
// person.FirstName = "Jane"; // 错误:init-only属性只能在构造或初始化时设置
初始化方式:
// 构造函数初始化
var person1 = new Person("Alice", "Smith");
// 对象初始化器
var person2 = new Person { FirstName = "Bob", LastName = "Johnson" };
// 复制并修改(with表达式)
var person3 = person1 with { LastName = "Williams" };
4. 值语义与相等性
record比较的是属性值,而非引用:
var p1 = new Person("John", "Doe");
var p2 = new Person("John", "Doe");
Console.WriteLine(p1 == p2); // 输出:True(值相等)
Console.WriteLine(ReferenceEquals(p1, p2)); // 输出:False(引用不同)
5. 继承与密封
- 继承:
record可以继承自其他record,但不能继承自普通类。 - 密封:使用
sealed关键字防止被继承。
public record Employee(string FirstName, string LastName, int EmployeeId)
: Person(FirstName, LastName); // 继承自Person
6. with 表达式(非破坏性修改)
创建一个新实例,复制原有属性并修改指定值:
var employee = new Employee("Alice", "Smith", 123);
var promotedEmployee = employee with { EmployeeId = 456 };
Console.WriteLine(employee.EmployeeId); // 输出:123(原实例不变)
Console.WriteLine(promotedEmployee.EmployeeId); // 输出:456
7. 解构方法
自动支持解构操作:
var person = new Person("John", "Doe");
var (first, last) = person; // 解构属性
8. 与 class/struct 的对比
| 特性 | record | class | struct |
|---|---|---|---|
| 类型 | 引用类型 | 引用类型 | 值类型 |
| 相等性 | 值语义 | 引用语义 | 值语义 |
| 默认不可变性 | 是(通过 init 访问器) | 否 | 否 |
| 内置方法 | 自动生成 | 需手动实现 | 需手动实现 |
| 继承 | 可继承自其他 record | 可继承自任何类 | 不可继承 |
9. 应用场景
- 数据传输对象(DTO):简洁的语法适合定义轻量级数据模型。
- 不可变对象:适合需要不可变性的场景(如多线程)。
- 领域模型:值语义使其更适合表示领域中的实体。
总结
record是 C# 中一种轻量级、不可变、具有值语义的类型,特别适合用于数据模型和需要频繁比较值的场景。它通过自动生成的方法减少了样板代码,提高了开发效率。
浙公网安备 33010602011771号