Choosing a type
On trails:CSTYPESstep 6/6
The kind of type follows from what the thing is.
- A class has identity, changing state or inheritance, such as a customer or a service. EF Core entities belong here: its guidance is to avoid records for them, because it tracks entities by reference equality.
- A record is its data, so two with the same values are the same thing, such as an address or a DTO. It has value equality,
withandToString. The positional or property form is a separate choice (see the () and noteRecords: the () way and the {} wayA record can be declared with its data in parentheses or in a body.Opens in a new tab). - A struct is a small, immutable single value, preferably
readonly. Areadonly record structadds value equality andwith. - An interface is a contract that unrelated types can fulfil. An abstract class adds shared behavior (see interfaces versus abstract classesInterfaces versus abstract classesTwo ways to define what a type must offer, and when each one fits.Opens in a new tab).
| Kind | Copying | Equality by default | Inheritance | |
|---|---|---|---|---|
class |
Reference | Shares the object | Reference | One base class, plus interfaces |
struct |
Value | Copies the value | Compares fields | Interfaces only |
interface |
Contract | Not applicable | Not applicable | Implemented by many types |
record |
Reference | Shares, and with makes a copy |
By value | One base record, plus interfaces |
record struct |
Value | Copies the value | By value | Interfaces only |
A wrong choice shows up later as a copy that wasn’t independent, an equality check that returns false, or an allocation on a hot path (see value types and reference typesValue types and reference typesA value type variable holds the value. A reference type variable holds a reference to an object.Opens in a new tab).