Records(C# 9+)是定义主要是不可变数据容器且具有基于值相等性的类型的简洁方式。它们自动生成样板代码(构造函数、相等性、ToString 等),使其适用于 DTOs、域值和数据建模。
使用位置语法定义 record
;
p1 = Person(, );
p1.Name;
Console.WriteLine(p1);
位置语法 record Person(string Name, int Age) 生成所有内容——属性、构造函数、ToString、相等性、解构——消除了常规类所需的样板代码。
var a = new Person("Ann", 30);
var b = new Person("Ann", 30);
a == b; // TRUE — records compare by VALUE (all properties equal)
// (a regular class would be FALSE here — classes compare by reference)
与类不同(按引用标识进行比较),records 按值进行比较——两个具有相同属性值的 records 是相等的。这正是数据对象所需要的。
public record Person(string Name, int Age); // properties are init-only (immutable)
var p1 = new Person("Ann", 30);
var p2 = p1 with { Age = 31 }; // `with` creates a COPY with some properties changed
// p1 unchanged (immutable); p2 = Person { Name = Ann, Age = 31 }
Records 默认不可变,with 表达式创建修改后的副本(非破坏性变异)——适用于处理不可变数据。
public record class Ref(int X); // a reference type (default) with value equality
public record struct Val(int X); // a VALUE type record (C# 10)
Records 是一个重要的现代 C# 功能(C# 9+),使定义不可变数据类型既简洁又正确,因此理解它们对现代 C# 开发很有价值。
它们的关键优势解决了实际需求:它们消除样板代码(从一行声明自动生成构造函数、属性、ToString、相等性和解构——相比之下常规类需要大量代码),并提供基于值的相等性(两个属性相等的 records 是相等的,不像类按引用比较)——这正是数据对象、DTOs 和域值所需的行为,也是类默认情况下的错误做法。
Records 还默认不可变,并具有优雅的**with 表达式**用于非破坏性变异(创建修改后的副本),支持日益流行的不可变、函数式风格,使代码更安全、更可预测。
理解 records——简洁语法、值相等性、带有 with 的不可变性和 record structs——对编写干净的现代 C# 很有价值,因为它们是建模数据(DTOs、API 模型、值对象、不可变状态)的惯用方式,在当今的代码库中广泛使用。
知道何时使用 record(具有值语义的不可变数据)与 class(具有标识和丰富行为的可变对象)反映了对现代 C# 的熟练掌握。
由于 records 大大简化了数据建模,同时提供了正确的相等性和不可变性——这些是之前繁琐且容易出错的常见需求——它们是一个重要的、频繁使用的功能,是现代、干净 C# 代码的标志。