【转】[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 的对比

特性recordclassstruct
类型 引用类型 引用类型 值类型
相等性 值语义 引用语义 值语义
默认不可变性 是(通过 init 访问器)
内置方法 自动生成 需手动实现 需手动实现
继承 可继承自其他 record 可继承自任何类 不可继承

9. 应用场景

  • 数据传输对象(DTO):简洁的语法适合定义轻量级数据模型。
  • 不可变对象:适合需要不可变性的场景(如多线程)。
  • 领域模型:值语义使其更适合表示领域中的实体。

总结

record是 C# 中一种轻量级、不可变、具有值语义的类型,特别适合用于数据模型和需要频繁比较值的场景。它通过自动生成的方法减少了样板代码,提高了开发效率。
posted on 2025-07-25 15:26  z5337  阅读(34)  评论(0)    收藏  举报