Generating Code in C#

How Source Generators, a New Feature Coming In C# 9.0, Will Help You Automate Code Creation


To start, let’s look at what it takes to implement equality for a type. Consider the simplistic definition of a person shown in Listing 1.

Listing 1 — Simple Definition Of A Person

public sealed class Person
{
  public Person(uint age, string name) =>
    (this.Age, this.Name) = (age, name);  public uint Age { get; }
  public string Name { get; }
}

If we wanted to compare twoPerson objects, we’d want to compare their Age and Name property values.

But there’s a lot of ceremony a developer needs to implement equality:

  • You must override Equals() and GetHashCode()

  • You must implement IEquatable<T>

  • You should override the == and != operators


In Listing 2, you can see that what was a simple definition is now a bit more complicated.

Listing 2 — Definition Of A Person With Equality­­

public sealed class Person  : IEquatable<Person?>
{
  public Person(uint age, string name) =>
    (this.Age, this.Name) = (age, name);  public uint Age { get; }
  public string Name { get; }
  public override bool Equals(object? obj) =>
    this.Equals(obj as Person);  public bool Equals(Person? other) =>
    other is not null &&
      this.Age == other.Age &&
      this.Name == other.Name;  public override int GetHashCode() =>
    HashCode.Combine(this.Age, this.Name);  public static bool operator ==(Person? left, Person? right) =>
    EqualityComparer<Person>.Default.Equals(left, right);  public static bool operator !=(Person? left, Person? right) =>
    !(left == right);
}

Implementing equality isn’t hard, but it’s cumbersome, time-consuming and error prone. What if the developer is having a bad day and flips the Boolean logic in one place? As developers, we want to automate all things for many reasons — to minimize human error, to create efficiencies, and because the more we can move to mechanized processes, the more we can focus on interesting and pressing problems.

Note that the