当前位置:首页 > C# > 正文

C#记录类型详解(打造安全可靠的不可变数据结构)

在现代软件开发中,不可变数据(Immutable Data)越来越受到重视。它能有效避免副作用、提升线程安全性,并让代码更易于推理和测试。C# 9.0 引入了 record 类型,为开发者提供了一种简洁而强大的方式来定义不可变的数据类型。

C#记录类型详解(打造安全可靠的不可变数据结构) C#记录类型 不可变数据 C#编程教程 record关键字 第1张

什么是记录类型(Record)?

简单来说,C#记录类型是一种专门用于表示不可变数据的引用类型。它默认具有以下特性:

  • 属性默认是 initreadonly 的,确保创建后不能被修改
  • 自动实现基于值的相等性比较(EqualsGetHashCode
  • 支持 with 表达式进行非破坏性修改(创建新实例)
  • 编译器自动生成 ToString() 方法,便于调试

基础语法:如何定义一个 record?

你可以像定义类一样定义 record,但使用 record 关键字:

public record Person(string FirstName, string LastName);

上面这行代码是一个 主构造函数语法(Primary Constructor),C# 编译器会自动为你生成:

  • 两个只读属性 FirstNameLastName
  • 一个接受这两个参数的构造函数
  • 重写的 EqualsGetHashCodeToString

不可变性是如何实现的?

让我们看看传统类与 record 在不可变性上的区别:

传统可变类(不推荐用于纯数据):

public class MutablePerson{    public string FirstName { get; set; }    public string LastName { get; set; }}

不可变 record(推荐):

public record ImmutablePerson(string FirstName, string LastName);// 使用示例var person = new ImmutablePerson("张", "三");// person.FirstName = "李"; // ❌ 编译错误!属性是只读的

如你所见,record 默认禁止修改属性,从而天然支持 不可变数据 设计原则。

使用 with 表达式进行“修改”

虽然 record 是不可变的,但我们经常需要基于现有对象创建一个“略有不同”的新对象。这时可以使用 with 表达式:

var original = new Person("王", "五");var updated = original with { FirstName = "赵" };Console.WriteLine(original);  // Person { FirstName = 王, LastName = 五 }Console.WriteLine(updated);   // Person { FirstName = 赵, LastName = 五 }

注意:original 对象没有被改变,updated 是一个全新的实例。这种模式非常适合函数式编程风格和并发场景。

值相等性 vs 引用相等性

普通类使用引用相等(两个变量指向同一内存地址才相等),而 record 使用值相等

var p1 = new Person("李", "四");var p2 = new Person("李", "四");Console.WriteLine(p1 == p2);        // True(值相等)Console.WriteLine(ReferenceEquals(p1, p2)); // False(不同对象)

这对单元测试、缓存、集合操作等场景非常有用,因为你关心的是“数据是否相同”,而不是“是不是同一个对象”。

何时使用 record?

record 非常适合以下场景:

  • DTO(数据传输对象)
  • 消息/事件载体
  • 配置对象
  • 函数式编程中的状态快照

但如果你需要复杂行为(方法)、继承体系或可变状态,传统的 class 仍然是更好的选择。

总结

通过 C# 的 record 关键字,我们可以轻松创建安全、简洁、不可变的数据类型。它不仅减少了样板代码,还提升了程序的可靠性和可维护性。无论你是刚接触 C#编程教程 的新手,还是有经验的开发者,掌握 record 都能让你的代码更现代、更健壮。

记住:在需要表示“数据是什么”而非“对象能做什么”时,优先考虑使用 record。