I previously wrote on how static members on a struct work as a more extension-friendly enum. This pattern has gotten even better as of C# 9.
The first improvement comes via records. Records are reference types with value-based equality. The main benefits are
- they don’t have the size restriction of structs
- They implement value-based
C# 9 also introduced source generators, which allow us to reflect at compile-time.
I created a generator, StaticMemberEnum.Generator, that automatically adds a
.KnownValues() method on declarations with the
[StaticMemberEnum] attribute. Now known values can be accessed without writing and maintaining boilerplate.
Other generators, like Generator.Equals, let you auto-implement equality and comparison if you still want to use a class or struct.
The best part is that generators work on older versions of C# as long you have a new enough SDK version installed! These generator power-ups can be dropped into existing code bases without upgrading language or framework versions!
In summary, most of the boilerplate with member enums has disappeared. Thanks to generators, this even retroactively applies to older language versions.