Start here. This is the direct spoken answer to practice first.
Why this question matters
The syntax is less important than the meaning of equality and change. A type representing an entity has different semantics from a value that can be replaced by another equal value.
I use a normal class for an object with identity and a lifecycle, where two instances can hold the same data but still represent different entities. I use a record class for value-oriented reference data when equality by components and non-destructive with updates are useful. I consider a record struct for a small value that benefits from value-type storage and copy semantics. I usually make value-oriented types immutable so their equality and hash behavior remain stable.