首页 > 解决方案 > 记录有通用的基类吗?

问题描述

在 .NET 类型系统中,所有引用类型都派生自,我认为System.Object所有值类型都派生自 。System.ValueType是否还有一个所有record类型都派生自的通用基类?如果不是,为什么不呢?

标签: c#c#-9.0

解决方案


是否还有一个所有记录类型都派生自一个通用基类?

不,至少不是任何特定于记录的东西。记录只是引用类型。它们可以直接来自System.Object或来自其他记录类型。

如果不是,为什么不呢?

它们不需要像值类型那样由运行时进行特殊处理。它们的所有特殊之处都在编译器为它们生成的代码中。


“根”记录

记录可以直接从 导出System.Object,无论是隐式还是显式,就像任何class可以一样。记录类型的第一级引导记录的内部,建立记录类型层次结构的根。

  1. 复制构造函数——一个受保护的构造函数,它接受对同一类型的引用并复制其属性。派生记录将从其复制构造函数中调用它。

  2. 克隆方法——如果它曾经是基类库的一部分,它本质上ICloneable<T>.Clone() <Clone>$是这样,但是这个方法有一个无法寻址的名称: . 当您使用with关键字时,它会调用<Clone>$,它使用复制构造函数创建一个新实例,然后编译器允许在初始化表达式中设置任何仅初始化属性。

  3. 平等成员——这是最重要的,因为记录是关于值语义的。和方法 from被覆盖,并被GetHashCode实现。还有一个名为的受保护属性用于相等比较,以确保通过仅比较公共部分来确保不同类型的记录不相等。和运算符也被重载。EqualsSystem.ObjectIEquatable<T>.Equals()EqualityContract==!=

  4. ToString方法-- 重载以显示记录的成员。它使用受保护的PrintMembers方法,调用类层次结构来构建具有所有属性值的字符串。

  5. Deconstruct方法——允许将记录解构为单个变量。


派生记录

当您为记录类型指定基本类型(除了System.Object)时,它必须是另一种记录类型,因为它需要记录类型层次结构的根建立的机制。派生记录类型定义了相同的成员,但被标记virtual的成员现在被标记为override

  1. 复制构造函数——这将调用基本记录的复制构造函数。

  2. 克隆方法——<Clone>$被重写以使用其复制构造函数返回更多派生类型。

有趣的事实:并没有使用新的协变返回特性在被覆盖的方法上声明一个更派生的返回类型,即使它返回了一个更派生的类型。这是因为 1) 它不需要,2) 它会使记录在 .NET 5.0 中不可用,因为在 .NET 5.0 运行时中添加了对该功能的支持。

  1. 平等成员——相同的方法被覆盖并定义了操作符,但任何新的属性都被认为是平等的。

  2. ToString方法——ToString并被PrintMembers覆盖。 ToString在字符串中生成实际的类名和花括号。不调用基本实现。 PrintMembers分别构建属性名称和值。

  3. Deconstruct方法——这里没有覆盖,因为基类的方法没有被标记virtual。如果引入了新属性,则签名与基类的签名不同,因此无需重写。如果没有引入新属性,则将该方法标记new为隐藏基类中的那个。


这就是为什么不需要记录的特殊基本类型的原因。


特别说明:

当记录被标记sealed时,通常会protected virtual(但不是protected override)的成员变为private。它的广泛程度取决于它是源自System.Object还是其他记录类型。

以上都没有考虑通过提供您自己的任何通常由编译器实现的方法的实现来进行定制。


推荐阅读