Match/Switch methods on members
Describe the feature
Mentioned as an alternative to the implemented solution under #125, I believe that Dunet-like Match/Switch methods would be a good addition as, opposed to C#'s switch expression/statements on the underlying value, it allows for compile-time guarantees that all members are explicitly handled.
I don't believe it's necessary to have the "this-member-or-else" matching that a library like Dunet has (i.e. MatchMyMember(Func<Union.MyMember, T> matched, Func<T> @else) as expecting specific members can still be done with simple x == MyEnum.MyMemberValue checks. Perhaps having the ability to pass in a state object to reduce/prevent closure allocations would be nice (see Dunet's stateful matching.)
Rough idea of how I see this looking (for Match)
[Intellenum<int>]
[Member("Motorbike", 1)]
[Member("ATV", 2)]
[Member("Reliant Robin", 3)]
public partial class VehicleType;
// Source-gen stubs
public TReturn Match<TReturn>(
Func<VehicleType, TReturn> matchMotorbike,
Func<VehicleType, TReturn> matchAtv,
Func<VehicleType, TReturn> matchReliantRobin
);
public void Switch( // SwitchAsync would also be nice
Action<VehicleType> matchMotorbike,
Action<VehicleType> matchAtv,
Action<VehicleType> matchReliantRobin
);
// Usage
var vehicleType = VehicleType.ReliantRobin;
var wheelCount = vehicleType.Match(
motorbike => 2,
atv => 4,
reliantRobin => 3
);
// "Vehicle "Reliant Robin" has 3 wheels"
Console.WriteLine($"Vehicle \"{vehicleType.Name}\" has {wheelCount} wheels.")
Potential issues
An issue I can foresee with this (which is also an issue in Dunet, but less due to type safety) is when the order of the enum's members is changed, the Match method will still be correct from a compiler's perspective, but the matched function may be different unless you explicitly specified parameter names. Sounds like a nasty thing to encounter in the real world.
The only way I see to get around this is to go fully down the discriminated union path and give members distinct types OR only type them as parameters to Match/Switch.
Something similar is present in OneOf library https://github.com/mcintyre321/OneOf/blob/6e02dbe75d0f20f198c640d4c04190a85c5ac9e6/OneOf/OneOfBaseT1.generated.cs#L47