Now that we’ve talked about the importance of implementing equality, the different kinds of equality, and about the contracts required of our implementations, we can get down to actually writing some code.
When our classes represent parties, places, or things that exist outside our application, we need entity equality to ensure that we only ever have at most a single instance in memory for every item in the real world.
The only thing we need compare when checking to see if two instances of
Person are equal is the unique identifier,
PersonId. We don’t care about any of the other properties because it’s the same person whether he calls himself Johnathon or Jon.
The C# 7 pattern matching syntax
obj is Person p is very convenient here, but its use hides another subtlety: We’re not using
GetType() to enforce that both classes have exactly the same type. This might seem to contradict my earlier post but it’s there for very good reason.
Many persistence frameworks, including Entity Framework and NHibernate among others, will create subclasses at runtime in order to inject functionality such as lazy loading. As a direct consequence, you might end up dealing with a
PersonProxy instead of a
Person - and having equality break would be bad idea.