How do records implement equality?
The compiler generates value-based equality for you: Equals, GetHashCode, == and != compare every field, plus a hidden EqualityContract property so that two records of different types are never equal, even with the same values.
Question
How do records implement equality?
What It Is
A record (a class) or record struct is a type the compiler fills with boilerplate. For equality, two record instances are equal when:
- they have the same
EqualityContract(by default,typeofthe record's own type), and - every field is equal according to
EqualityComparer<T>.Default.
Since a record is still a reference type, ReferenceEquals(a, b) keeps telling you whether they are the same object, but a == b now means "same values".
The Shallow Part
The comparison is field by field, one level deep. If a field is a List<T> or an array, it's compared with that type's own Equals, which is reference equality. Two records with lists containing the same items are not equal.
The same goes for with expressions: they make a shallow copy. The new record shares the same list instance with the original.
Practical Example
csharppublic record Point(int X, int Y);
public record ColoredPoint(int X, int Y, string Color) : Point(X, Y);
public record Order(int Id, List<string> Items);
new Point(1, 2) == new Point(1, 2); // true
new Point(1, 2) == new ColoredPoint(1, 2, "red"); // false: different EqualityContract
var a = new Order(1, ["book"]);
var b = new Order(1, ["book"]);
a == b; // false: lists compared by reference
var c = a with { Id = 2 };
c.Items.Add("pen"); // a.Items also has "pen" nowSolution and Conclusion
Records are ideal for immutable data whose fields are themselves values (numbers, strings, other records). If you need collections inside them, prefer immutable collections and override Equals(R? other) and GetHashCode when you want sequence equality. And remember that with never deep-copies.