Identity versus value
Value objects are equal by their values. Entities are equal by their identity. Two flight-note value objects with the same key and body are the same note. Two aggregates are the same aggregate only when their Id matches, even if every other field differs. That’s the whole distinction: a VO is what it contains; an entity is who it is.
Fusion’s Entity<TId> base makes this sharp in a way that surprises people. It doesn’t just implement identity equality, it refuses value equality entirely: Equals, GetHashCode, and == all throw.
public override bool Equals(object? obj) =>
throw new NotImplementedException("Don't use equality operators with entities.");
public override int GetHashCode() =>
throw new NotImplementedException("Don't use equality operators with entities.");
public static bool operator ==(Entity<TId>? left, Entity<TId>? right) =>
throw new NotImplementedException("Don't use equality operators with entities.");Why be so aggressive? Because comparing two entities with == almost always means you wanted to compare their Ids and got it subtly wrong. By throwing, the base turns a silent bug into a loud one at the exact call site. When you need to know if two entity references are the same entity, compare a.Id == b.Id.
Try it yourself
Confirm entity == throws
Verify the aggressive guard is real, not a story.
Reading domain/Entity.cs, every equality path — Equals(object?), Equals(Entity<TId>?), GetHashCode(), operator ==, operator != — throws NotImplementedException("Don't use equality operators with entities."). So aggregateA == aggregateB doesn't return false, it throws, which forces you to write aggregateA.Id == aggregateB.Id instead.
The two kinds of equality
One sentence each.
How is a value object equal to another, and how is an entity equal to another?
Reveal answer
A value object is equal when all its value components match (equality by value). An entity is equal only when its identity (Id) matches, regardless of its other fields (equality by identity). Fusion's Entity base makes == throw so you must compare Ids explicitly.
Compare two entities
You have two FlightDisruptionAggregate references and want to know if they're the same aggregate. What do you write?
Show answer
Correct answer: C — a.Id == b.Id
Compare identities: a.Id == b.Id. In Fusion, a == b and a.Equals(b) throw by design (Entity forbids value equality), and ReferenceEquals only tells you if they're the same object reference, not the same entity.