如何在 C# 9 中复制/克隆记录?
Posted
技术标签:
【中文标题】如何在 C# 9 中复制/克隆记录?【英文标题】:How to copy/clone records in C# 9? 【发布时间】:2021-01-07 16:17:00 【问题描述】:C# 9 records feature specification 包括以下内容:
一个记录类型包含两个复制成员:
采用记录类型的单个参数的构造函数。它是 称为“复制构造函数”。综合公众 具有编译器保留名称的无参数实例“克隆”方法
但我似乎无法调用这两个复制成员中的任何一个:
public record R(int A);
// ...
var r2 = new R(r); // ERROR: inaccessible due to protection level
var r3 = r.Clone(); // ERROR: R does not contain a definition for Clone
由此,我了解到构造函数受到保护,因此无法在记录的继承层次结构之外访问。所以我们留下了这样的代码:
var r4 = r with ;
但是克隆呢?根据上述规范,克隆方法是公开的。但它的名字是什么?或者它是一个有效的随机字符串,因此不应在记录的继承层次结构之外调用它?如果是这样,深拷贝记录的正确方法是什么?从规范看来,一个人能够创建自己的克隆方法。是这样吗?它应该如何工作的一个例子是什么?
【问题讨论】:
“但是克隆呢?” 这就是with
表达式的作用。您不应该知道“克隆”方法的名称。这就是“编译器保留”的意思。它支持with
表达式。
表上的实现细节:名字是<Clone>$
。按照设计,您不能自己调用它。
它没有。这种克隆机制是浅拷贝。您链接的文档在任何地方都不包含“深度”一词。如果你想要一个深拷贝,你需要自己实现。
@madreflection 谢谢。我认为让我感到困惑的是文档中“复制”和“克隆”的使用,但是您没有使用“深度”这个词是正确的,因此必须以其他方式实现。我也对文档的声明“如果基本记录中存在虚拟“克隆”方法,......”感到困惑,据我所知,这始终是综合创建的 Clone() 方法,而不是用户定义的一;尝试自己创建这样的方法会产生错误。
应该注意 imo,“浅拷贝”是一个定义明确的概念,而“深拷贝”不是。
【参考方案1】:
但是克隆呢?
var r4 = r with ;
在 r 上执行浅层克隆。
根据上述规范,克隆方法是公开的。但是它的名字是什么?
C# 编译器有一个相当常见的技巧,它为生成的成员提供名称,这些名称在 C# 中是非法的,但在 IL 中是合法的,因此即使它们是公共的,也无法从编译器中调用它们。在这种情况下,Clone
方法的名称是 <Clone>$
。
如果是这样,深拷贝记录的正确方法是什么?
深度复制你不走运。然而,由于理想情况下记录应该是不可变的,因此浅拷贝、深拷贝和原始实例在实践中应该没有区别。
从规范看来,一个人能够创建自己的克隆方法。是这样吗?它应该如何工作的一个例子是什么?
很遗憾,这并没有进入 C# 9,但很有可能会出现在 C# 10 中。
【讨论】:
是否有关于 C# 10 中的自定义Clone
的讨论?感觉就像引入它会使其遭受ICloneable
一直存在的相同问题,不知道<Clone>$
是否会进行浅克隆或自定义深度克隆。
对于 C# 10 根本没有讨论过。也许 C# 11...
所以他们引入了表达式,并且只对记录起作用,不能用于其他任何东西?
现在,是的@John以上是关于如何在 C# 9 中复制/克隆记录?的主要内容,如果未能解决你的问题,请参考以下文章