Death by a thousand cuts

As you might have noticed from my posts in the past I really dislike it when there is a part of the C# language that seems to be unnecessarily lacking.  For example, not being able to take a delegate to a property.  It's a perfectly reasonable thing to do.  You run into it in practice.  And, it's something that is completely possible to do without any difficulty in the language.  Having methods be able to do this but not have properties (which are just glorified methods) have the same capability just annoys me.  Similaryly, not having something as nice as covariant return types is also quite aggravating.  It could be added without breaking any code, and it ends up making life much nicer for both API developers and consumers.

There are an enormous number of these "nuisances", and (unsurprisingly) we've found one more.  It's often the case that you want to have an operation that works specifically on an enum.  For example you might want to take the unsafe Enum.Parse method and replace it with a typesafe one.  Currently Enum.Parse looks like.

class Enum

{

public static Enum Parse(Type enumType, string enumMemberName) { ... }

}

 

To use it you have to write code like:

Color c = (Color)Color.Parse(typeof(Color), someString);

 

(holy redundancy batman!) *shudder*.

So i'd love to be able to write something helpful like this:

class EnumUtilities<T> where T : enum

{

     public static T Parse(string enumMemberName)

     {

          return (T)Enum.Parse(typeof(T), enumMemberName);

     }

     //Returns true if there is a single member in this enum equal to "value"

     public bool IsMember(T value) { ... }

     //Returns true if "value" can be represented as the union of any members of this enum

     public bool IsUnionOfMembers(T value) { ... }

}

...

Color c = EnumUtilities<Color>.Parse(someString);

Debug.Assert(EnumUtilities<Color>.IsMember(someColorHandedToYouByAnother));

 

Seems reasonable right?  A useful way to get around the limitations of the built in enum type by using generics.  And, instead of the ugly non-typesafe redundant calls you need to do now you have a nice safe method that is checked at compile type to be ok.

But... no.

Of course, once again, i try to do this and i experience another cut.  "enum is not a valid constraint for a type parameter".  Sigh...

We already allow you to contrain to reference types or value types.  So why not allow you to constrain to enums?  It's just one of those missing things that really annoys you once you hit it.  Of course, there are workarounds.  You could do this:

class EnumUtilities<T> where T : struct

{

     static EnumUtilities

     {

          if (!typeof(T).IsSubclassOf(typeof(Enum)))

          {

              throw new ArgumentException("The type parameters T must be an enum");

          }

}

     public static T Parse(string enumMemberName)

     {

          return (T)Enum.Parse(typeof(T), enumMemberName);

     }

}

...

//Compiles fine and fails at runtime

int c = EnumUtilities<int>.Parse(someString);

 

I hate having things fail at runtime.  I'm a big fan of the compiler figuring this all out for me and telling me right when i compile.  But, nope.  Once again I have no choice but ugly workarounds and asking myself "why couldn't this just be consistant?"