A record
behaves like a class
in that it is a reference type however the compiler provides automatic equality and cloning much like it does for a struct
(a value type).
Code
C#
record Person
{
public string LastName { get; }
public string FirstName { get; }
public Person(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
}
C#
class Person : IEquatable<Person>
{
public string FirstName { get; private init; }
public string LastName { get; private init; }
public Person(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
public override int GetHashCode()
{
int hash = 17;
if (FirstName != null) hash = hash * 23 + FirstName.GetHashCode();
if (LastName != null) hash = hash * 23 + LastName.GetHashCode();
return hash;
}
public bool Equals(Person other)
{
if (Object.ReferenceEquals(this, other)) return true;
if (other == null || other.GetType() != typeof(Person)) return false;
return other.FirstName == FirstName && other.LastName == LastName;
}
public override bool Equals(object obj)
{
return Equals(obj as Person);
}
public static bool operator ==(Person a, Person b)
{
if (Object.ReferenceEquals(a, null))
return Object.ReferenceEquals(b, null);
return a.Equals(b);
}
public static bool operator !=(Person a, Person b)
{
return !(a == b);
}
}
Notes
- Extended to
struct
in C# 10.0](/10.0/record-structs)
When declaring a record the compiler also produces support for:
- cloning via
with
- a default implementation of
ToString
that prints the value of each member - a new
EqualityContract
property - a
Deconstruct
method for supporting deconstruction patterns