Is there a common base class for records?

百般思念 提交于 2021-01-28 12:37:35

问题


In the .NET type system all reference types derive from System.Object, all value types from System.ValueType I think. Is there also a common base class all record types are derived from? If not, why not?


回答1:


Is there also a common base class all record types are derived from?

No, at least not anything specific to records. Records are just reference types. They can derive directly from System.Object or from other record types.

If not, why not?

They don't require special handling by the runtime like value types do. Everything that's special about them is in the code that the compiler generates for them.


"Root" Records

A record can derive directly from System.Object, either implicitly or explicitly, just as any class can. That first level of record type bootstraps the internals of a record, establishing the root of a record type hierarchy.

  1. Copy constructor -- A protected constructor that accepts a reference to the same type and copies its properties. Derived records will call this from their copy constructors.

  2. Clone method -- It's essentially what ICloneable<T>.Clone() would have been had it ever been a part of the Base Class Library, but this one has an unaddressable name: <Clone>$. When you use the with keyword, it calls <Clone>$, which creates a new instance using the copy constructor, and then the compiler allows any init-only properties to be set within the initializer expression.

  3. Equality members -- This is the big one, since records are about value semantics. The GetHashCode and Equals methods from System.Object are overridden, and IEquatable<T>.Equals() is implemented. There's also a protected property named EqualityContract which is used in the equality comparison to ensure that records of different types are not considered equal by comparing only the common parts. The == and != operators are overloaded, as well.

  4. ToString method -- Overloaded to display the members of the record. It uses a protected PrintMembers method, which is called up the class hierarchy to build the string with all the properties' values.

  5. Deconstruct method -- Enables the record to be deconstructed into individual variables.


Derived records

When you specify a base type (other than System.Object) for a record type, it must be another record type because it requires the mechanisms established by the root of the record type hierarchy. The derived record type defines the same members, but members that were marked virtual are now marked override.

  1. Copy constructor -- This will call the base record's copy constructor.

  2. Clone method -- <Clone>$ is overridden to return the more derived type using its copy constructor.

Fun fact: This does not use the new covariant returns feature to declare a more derived return type on the overridden method, even though it returns a more derived type. That's because 1) it doesn't need to, and 2) it would've made records unusable except in .NET 5.0 since support for the feature was added in the .NET 5.0 runtime.

  1. Equality members -- The same methods are overridden and operators defined, but with any new properties considered for equality.

  2. ToString method -- ToString and PrintMembers are overridden. ToString produces the actual class name and curly braces in the string. The base implementation is not called. PrintMembers separately builds the property names and values.

  3. Deconstruct method -- There's no overriding here because the base class's method isn't marked virtual. If new properties are introduced, the signature is different from that of the base class so there's nothing to override. If no new properties are introduced, the method is marked new to shadow the one in the base class.


That is why a special base type for records isn't necessary.


Special notes:

When a record is marked sealed, members that normally would be protected virtual (but not protected override) become private. How extensive that is depends on whether it derives from System.Object or another record type.

None of the above takes into account customization by way of providing your own implementation of any of the methods that are normally implemented by the compiler.



来源:https://stackoverflow.com/questions/65421125/is-there-a-common-base-class-for-records

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!