API design: choosing between non-ideal options
So, UnconstrainedMelody is coming on quite nicely. It now has quite a few useful options for flags enums, "normal enums" and delegates. However, there are two conflicting limitations which leave a couple of options. (Other related answers on Stack Overflow have suggested alternative approaches, basically.)
Currently, most of the enums code is in two classes: Flags and Enums. Both are non-generic: the methods within them are generic methods, so they have type parameters (and constraints). The main benefit of this is that generic type inference only applies to generic methods, and I definitely want that for extension methods and anywhere else it makes sense.
The drawback is that properties can't be generic. That means my API is entirely expressed in terms of methods, which can be a pain. The option to work around this is to have a generic type which properties in. This adds confusion and guesswork - what call is where?
To recap, the options are:
IList<Foo> foos = Enums.GetValues<Foo>();
string firstDescription = foos[0].GetDescription();
IList<Foo> foos = Enums<Foo>.Values;
string firstDescription = Enums<Foo>.GetDescription(foos[0]);
IList<Foo> foos = Enums<Foo>.Values;
string firstDescription = foos[0].GetDescription();
All of these are somewhat annoying. If we only put extension methods into the nongeneric class, then I guess users would never need to really think about that - they'd pretty much always be calling the methods via the extension method syntactic sugar anyway. It still feels like a pretty arbitrary split though.
Any thoughts? Which is more important - conceptual complexity, or the idiomatic client code you end up with once that complexity has been mastered? Is it reasonable to make design decisions like this around what is essentially a single piece of syntactic sugar (extension methods)?
(By the way, if anyone ever wanted justification for extension properties, I think this is a good example... Description feels like it really should be a property.)