c# - 记录有通用的基类吗?
问题描述
在 .NET 类型系统中,所有引用类型都派生自,我认为System.Object
所有值类型都派生自 。System.ValueType
是否还有一个所有record
类型都派生自的通用基类?如果不是,为什么不呢?
解决方案
是否还有一个所有记录类型都派生自一个通用基类?
不,至少不是任何特定于记录的东西。记录只是引用类型。它们可以直接来自System.Object
或来自其他记录类型。
如果不是,为什么不呢?
它们不需要像值类型那样由运行时进行特殊处理。它们的所有特殊之处都在编译器为它们生成的代码中。
“根”记录
记录可以直接从 导出System.Object
,无论是隐式还是显式,就像任何class
可以一样。记录类型的第一级引导记录的内部,建立记录类型层次结构的根。
复制构造函数——一个受保护的构造函数,它接受对同一类型的引用并复制其属性。派生记录将从其复制构造函数中调用它。
克隆方法——如果它曾经是基类库的一部分,它本质上
ICloneable<T>.Clone()
会<Clone>$
是这样,但是这个方法有一个无法寻址的名称: . 当您使用with
关键字时,它会调用<Clone>$
,它使用复制构造函数创建一个新实例,然后编译器允许在初始化表达式中设置任何仅初始化属性。平等成员——这是最重要的,因为记录是关于值语义的。和方法 from被覆盖,并被
GetHashCode
实现。还有一个名为的受保护属性用于相等比较,以确保通过仅比较公共部分来确保不同类型的记录不相等。和运算符也被重载。Equals
System.Object
IEquatable<T>.Equals()
EqualityContract
==
!=
ToString
方法-- 重载以显示记录的成员。它使用受保护的PrintMembers
方法,调用类层次结构来构建具有所有属性值的字符串。Deconstruct
方法——允许将记录解构为单个变量。
派生记录
当您为记录类型指定基本类型(除了System.Object
)时,它必须是另一种记录类型,因为它需要记录类型层次结构的根建立的机制。派生记录类型定义了相同的成员,但被标记virtual
的成员现在被标记为override
。
复制构造函数——这将调用基本记录的复制构造函数。
克隆方法——
<Clone>$
被重写以使用其复制构造函数返回更多派生类型。
有趣的事实:这并没有使用新的协变返回特性在被覆盖的方法上声明一个更派生的返回类型,即使它返回了一个更派生的类型。这是因为 1) 它不需要,2) 它会使记录在 .NET 5.0 中不可用,因为在 .NET 5.0 运行时中添加了对该功能的支持。
平等成员——相同的方法被覆盖并定义了操作符,但任何新的属性都被认为是平等的。
ToString
方法——ToString
并被PrintMembers
覆盖。ToString
在字符串中生成实际的类名和花括号。不调用基本实现。PrintMembers
分别构建属性名称和值。Deconstruct
方法——这里没有覆盖,因为基类的方法没有被标记virtual
。如果引入了新属性,则签名与基类的签名不同,因此无需重写。如果没有引入新属性,则将该方法标记new
为隐藏基类中的那个。
这就是为什么不需要记录的特殊基本类型的原因。
特别说明:
当记录被标记sealed
时,通常会protected virtual
(但不是protected override
)的成员变为private
。它的广泛程度取决于它是源自System.Object
还是其他记录类型。
以上都没有考虑通过提供您自己的任何通常由编译器实现的方法的实现来进行定制。
推荐阅读
- amazon-web-services - 为多个目标组创建单个 cloudwatch 警报?
- node.js - 无法将 mongoDB 保存调用的响应返回到前端
- java - 即使在应用程序关闭时也保存用户选择的图像?
- java - Spring Webflux Security - 基于客户端证书的授权端点
- python-3.x - 如何在 python 3 的列表字符串中将 ' ' 替换为 '0'?
- pdf - 使用 ghostscript 为 postscript 文件中的某些页面添加 Duplex 选项
- angular - ts-toolbelt 在 node_modules 上给出错误。类型别名“MergeList”循环引用自身
- python - python中未定义全局变量名称错误
- json - 动态结构定义
- hiveql - 如何在日期列上查询 2 个表,如果不存在匹配的日期,那么我们必须加入下一个最大日期