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(string FirstName, string LastName);
// The above positional syntax is shorthand for:
record Person
{
public string FirstName { get; init; }
public string LastName { get; init; }
public Person(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
}
// Create modified copies with `with` expressions
var person = new Person("John", "Smith");
var other = person with { LastName = "Jones" };C#
class Person : IEquatable<Person>
{
public string FirstName { get; private set; }
public string LastName { get; private set; }
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
structin C# 10.0
When declaring a record the compiler also produces support for:
- cloning via
with - a default implementation of
ToStringthat prints the value of each member - a new
EqualityContractproperty - a
Deconstructmethod for supporting deconstruction patterns