C# 是否有记录的通用基类?

C# 是否有记录的通用基类?,c#,c#-9.0,C#,C# 9.0,在.NET类型系统中,所有引用类型都源自system.Object,所有值类型都源自system.ValueType。是否还有一个通用的基类所有记录类型都是从中派生的?若否,原因为何 是否还有一个通用的基类来派生所有记录类型 不,至少没有任何特定的记录。记录只是引用类型。它们可以直接从System.Object或其他记录类型派生 若否,原因为何 它们不像值类型那样需要运行时进行特殊处理。它们的所有特殊之处都在编译器为它们生成的代码中 “根”记录 记录可以直接从System.Object派生,可

在.NET类型系统中,所有引用类型都源自
system.Object
,所有值类型都源自
system.ValueType
。是否还有一个通用的基类所有
记录
类型都是从中派生的?若否,原因为何

是否还有一个通用的基类来派生所有记录类型

不,至少没有任何特定的记录。记录只是引用类型。它们可以直接从
System.Object
或其他记录类型派生

若否,原因为何

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


“根”记录 记录可以直接从
System.Object
派生,可以隐式派生,也可以显式派生,就像任何
可以派生一样。第一级记录类型引导记录的内部,建立记录类型层次结构的根

  • 复制构造函数——接受对同一类型的引用并复制其属性的受保护构造函数。派生记录将从其副本构造函数调用此函数

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

  • 平等成员——这是一个大问题,因为记录是关于值语义的。覆盖来自
    System.Object
    GetHashCode
    Equals
    方法,并实现
    IEquatable.Equals()
    。还有一个名为
    EqualityContract
    的受保护属性,用于相等性比较,以确保仅通过比较公共部分,不同类型的记录不会被视为相等。
    ==
    =运算符也被重载

  • ToString
    方法
    ——重载以显示记录的成员。它使用受保护的
    PrintMembers
    方法,在类层次结构中调用该方法来构建包含所有属性值的字符串

  • 解构
    方法
    ——允许将记录解构为单个变量


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

  • 复制构造函数——这将调用基记录的复制构造函数

  • 克隆方法--
    $
    被重写,以使用其复制构造函数返回更派生的类型

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

  • 相等成员——覆盖相同的方法并定义运算符,但考虑任何新的相等属性

  • ToString
    方法
    --
    ToString
    PrintMembers
    被覆盖
    ToString
    在字符串中生成实际的类名和花括号。不调用基本实现<代码>打印成员
    分别生成属性名称和值

  • 解构
    方法
    ——这里没有重写,因为基类的方法没有标记为
    虚拟
    。如果引入了新属性,则签名与基类的签名不同,因此没有任何可重写的内容。如果没有引入新属性,则将该方法标记为
    new
    ,以隐藏基类中的属性


  • 这就是为什么不需要记录的特殊基类型


    特别注意事项:

    当记录被标记为
    密封
    时,通常受
    保护的虚拟
    (但不受
    保护的覆盖
    )成员将变为
    私有
    。其扩展程度取决于它是从
    System.Object
    还是其他记录类型派生而来


    以上任何一项都不考虑通过提供编译器通常实现的任何方法的您自己的实现来进行自定义。

    ValueType
    也派生自
    对象
    。它们是没有特殊基类的普通类,并通过一些特殊的基类实现
    IEquatable
    命名方法。奇怪的是,它们甚至没有任何类型的描述符
    属性
    ,也没有特殊的接口来区分它们。