掌握 C# 中的记录:深入了解 C# 9 的不可变性功能
内容提要
C# 9引入了记录(records),一种新的引用类型,简化了不可变数据对象的创建。记录特别适用于需要不可变性和值相等性的场景,如DTO和配置对象。记录提供了内置的值相等性和不可变性,并可以通过额外的方法进行定制。它们还支持继承,并可以用于以现代和高效的方式定义数据结构。记录特别适用于DTO、配置对象和事件溯源系统。通过利用记录,开发人员可以创建更可靠和可维护的代码。
延伸解读
记录与类的核心差异
C# 9 记录与传统类在相等性语义上存在根本区别。类默认基于对象引用判断相等,而记录内置基于值的相等性,只要属性值相同,两条记录即被视为相等。这一特性使记录特别适合需要值语义的场景,如 DTO 和配置对象,能避免因引用不同而导致的意外不等判断。
不可变性与 with 表达式
记录默认不可变,创建后无法修改属性,这有助于减少状态变化引发的错误。当需要基于现有记录生成新记录时,可使用 with 表达式,它会复制原有值并应用指定更改,返回一个新实例。这种方式在保持不可变性的同时,提供了灵活的数据更新手段。
继承与自定义的平衡
记录支持继承,允许构建不可变类型的层次结构,例如从 Person 派生出 Employee。同时,记录可通过添加方法或覆盖现有方法进行定制,如添加 FullName 属性或重写 ToString。但需注意,继承可能增加值相等性比较的复杂性,设计时应权衡层次结构的必要性。
可变记录的风险
虽然记录默认不可变,但也可定义可变记录,即使用可写属性。然而,这违背了记录的主要设计原则,可能导致值相等性行为变得不可预测,并失去不可变性带来的线程安全等优势。因此,除非有明确理由,否则应避免使用可变记录。
Q&A
C# 9 中的记录是什么?
C# 9 中的记录是一种新的引用类型,简化了不可变数据对象的创建,具有内置的值相等性和不可变性。
记录在什么场景下特别有用?
记录特别适用于需要不可变性和值相等性的场景,如数据传输对象(DTO)和配置对象。
如何创建一个新的记录实例并修改某个属性?
可以使用 with-expressions 创建新记录实例,例如:var updatedPerson = person with { LastName = 'Smith' };
记录的值相等性是如何工作的?
记录提供内置值相等性,相同数据的记录被视为相等,例如:person1 == person2 返回 true。
如何自定义记录的行为?
可以通过添加方法或覆盖现有方法来自定义记录,例如定义 FullName 属性或重写 ToString 方法。
记录支持继承吗?
是的,记录支持继承,可以创建不可变类型的层次结构,例如定义 Employee 记录继承自 Person 记录。