记录结构的目的是什么?

8

C# 9 增加了 record 类型,这是一种使用基于值的相等性的新引用类型。

C# 10 引入了 record struct 语法,用于定义一个具有类似于 record 的属性的值类型 (https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/record)。

创建一个值类型版本的类型并不寻常,因为它原本是作为引用类型创建的,同时也具有基于值的相等性 - 这肯定会消除使用该类型的大部分好处。

为什么你会想要声明一个 record struct 呢?

我是否遗漏了其他东西?


2
另一个 SO 的帖子可能会有所帮助 https://dev59.com/3FIG5IYBdhLWcg3whAIW - N Subedi
3
请查看此文章:https://nietras.com/2021/06/14/csharp-10-record-struct/ (注意,记录结构不是不可变的。只读记录结构是不可变的) - Evk
3
阅读来自 Evk 的文章,并检查第二个代码片段。仅这就足以介绍它了。这是一个非常常见的代码结构,消除大量样板代码是一个优点。但请参阅此文章 - 还有许多其他微小的、看似不相关的添加,当它们聚集在一起时,形成了一个非常方便的类似元组的工具,比当前的几种元组类型更方便。 - quetzalcoatl
3
仅仅为了减少代码而使用新类型并不是明智的选择 - 改进语法更有意义。但这正是record所做的。它并没有引入新类型,而是引入了一种新的编写classstruct声明的方式,并自动生成样板文件。仅仅通过语法无法使现有的类或结构体表现出这种行为,那将会非常复杂 - 而改变元组的工作方式,虽然原则上可能,但已经过时了,因为大量现有的代码依赖于它们现有的行为。 - Jeroen Mostert
2
所有的结构体都是值类型,因此显然包括 record struct。而且,record 现在与 record class 是同一回事。这并不否定我所说的内容。当文档谈到 record 作为“可以创建代替类或结构体的新引用类型”时,这些文档误导到了错误的地步;如果 record 不是现有代码的普通旧类,那么它们将不会有一半的用处!基于值的相等性和不可变性可以手动实现在类上,但这很繁琐。record 消除了这种繁琐。 - Jeroen Mostert
显示剩余11条评论
1个回答

12

record struct 的主要优点如下:

  1. 它允许您将 struct 定义简化为单行。
  2. 它提供了 ==!= 运算符的重载,因此可以使用这些运算符进行比较,而无需额外定义运算符重载。对于 struct,您只能使用默认的 Equals() 方法进行比较。
  3. 它提供了比 struct 更全面的默认 ToString() 方法。 record structToString() 方法将生成 record struct 名称、其属性名称和值。而 struct 的默认 ToString() 方法仅生成 struct 名称。
  4. 相比于 struct,它提供了性能优势(高达 20 倍更快 - https://anthonygiretti.com/2021/08/03/introducing-c-10-record-struct/)。
在某些方面,record 类型类似于值元组,它们提供默认运算符重载并具有 ToString() 方法,该方法更接近于 record struct(值元组的 ToString() 方法生成其所有属性的值)。
然而,值元组仅用于临时使用,而 record struct 可用于定义将被重复使用的类型。

注意

record / record class 默认为不可变类型,但 record struct 不是,因此如果您想要一个不可变的 record struct,您必须使用 readonly record struct

最终备注

考虑到使用 record struct 相对于 struct 的好处,除非有一些非常特定的原因,否则最好总是优先选择 record struct
看起来 record structstruct 的增强版,保留了旧类型,以便不会删除 struct 的现有行为/功能。

2
顺便说一下,对于像我一样偶然看到这篇帖子的人:只有在不实现IEquatable<T>和GetHashCode时,性能提升才是明显的。这甚至在基准测试中都有提到。此外,如果你自己在结构体上实现这些东西,可能会获得非常微小的性能改进。基准测试的实际页面在这里:https://nietras.com/2021/06/14/csharp-10-record-struct/ 所以,我的建议是根据你自己的需求选择最方便的方式(例如性能/控制方面,使用结构体;否则使用记录)。 - Mike
1
@Mike我的目标并不是鼓励其使用,而更多地是寻找其存在的原因并陈述它们。一如既往,人们应该权衡自己的需求,选择最好的而不是自动尝试优化他们可能想到的一切。 - YungDeiza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接