C# 10 Records
2023-02-03 C# record GetHashCode Equals HashSet withI prefer immutable types when designing my code, so usually ended up with a class where all properties are getters only and constructor to fill them on initialization. Something like this
public class Anchor
{
public Anchor(string anchor, string file)
{
AnchorName = anchor;
FileName = file;
}
public string AnchorName { get; }
public string FileName { get; }
public override bool Equals(object obj)
{
return obj is Anchor anchor &&
AnchorName == anchor.AnchorName &&
FileName == anchor.FileName;
}
public override int GetHashCode()
{
int hashCode = -1749314865;
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(AnchorName);
hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(FileName);
return hashCode;
}
}
The class able also implements Equals
to compare the contents and GetHashCode
to use with data types like HashSet
.
Since C# 9 it is possible to use init
modifier to properties, allowing to init them with curly bracket syntax and saving some typing (auto-generating with Visual Studio really) for constructors
public class Anchor
{
public string AnchorName { get; init; }
public string FileName { get; init; }
// Equals and GetHashCode as before ...
}
With C# 10 this moved a bit further with introduction of records
. All implementation above can be done with just
public record class Anchor(string AnchorName, string FileName);
And we get some bonus to above
- autogenerated
ToString
implementation to print something likeAnchor { AnchorName = ID_002, FileName = Requirements02.docx }
- autogenerated comparators considering all properties
- hashing using all properties
- non-destructive mutator
with
Here is example of keeping just unique entries
HashSet<Anchor> found = new HashSet<Anchor>();
found.Add(new Anchor("ID_001", "Requirements01.docx"));
found.Add(new Anchor("ID_002", "Requirements02.docx"));
found.Add(new Anchor("ID_001", "Requirements01.docx"));
foreach(Anchor a in found)
Console.WriteLine(a);
And cloning entry with mutation of some properties
var a1 = new Anchor("ID_003", "Requirements01.docx");
var a2 = a1 with { AnchorName = "ID_004" };
Console.WriteLine($"{a1} and {a2}");