问题
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.
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.
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 thewith
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.Equality members -- This is the big one, since records are about value semantics. The
GetHashCode
andEquals
methods fromSystem.Object
are overridden, andIEquatable<T>.Equals()
is implemented. There's also a protected property namedEqualityContract
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.ToString
method -- Overloaded to display the members of the record. It uses a protectedPrintMembers
method, which is called up the class hierarchy to build the string with all the properties' values.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
.
Copy constructor -- This will call the base record's copy constructor.
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.
Equality members -- The same methods are overridden and operators defined, but with any new properties considered for equality.
ToString
method --ToString
andPrintMembers
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.Deconstruct
method -- There's no overriding here because the base class's method isn't markedvirtual
. 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 markednew
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