SoaperGEM SoaperGEM - 1 month ago 12
C# Question

Is it possible to write an extension method for a generic Enum type?

Over on this StackOverflow question, I found this really nice helper method for parsing a string into a generic Enum value:

public static T ParseEnum<T>(string value)
{
return (T) Enum.Parse(typeof(T), value, true);
}


I'd like to change this from a helper method into an extension method, but I'm not all that familiar with using generics, so I'm not sure if/how that would work.

I tried this, but as you'll quickly see this code doesn't actually compile:

public static T ParseEnum(this T myEnum, string value)
{
return (T) Enum.Parse(typeof(myEnum), value, true);
}


And I also tried this, but this doesn't do it either:

public static Enum ParseEnum(this Enum myEnum, string value)
{
return Enum.Parse(typeof(myEnum), value, true);
}


Is it even possible to do what I'm asking about here?

Answer

When writing an extension method, the first thing you need to do is figure out how you want to call it. I.e. what are you extending?

In the case of parsing a string and returning an enum value, the only thing that really makes sense is to extend the string class. In that view, this is what the extension method would look like:

    public static T ParseEnum<T>(this string text)
    {
        return (T)Enum.Parse(typeof(T), text);
    }

You would call it like this:

Pets pet = "Cat".ParseEnum<Pets>();

Another alternative uses type inference, at the cost of a by-reference argument (which I prefer to avoid):

    public static void ParseEnum<T>(this string text, out T t)
    {
        t = (T)Enum.Parse(typeof(T), text);
    }

You would call that like this:

Pets pet;

"Cat".ParseEnum(out pet);

IMHO this is not as good, even though you get type inference, because you can't use the method call in an expression.

Note that the syntax Pets.ParseEnum("Cat") is not going to work, because Pets is a type name, not a type instance, and you can extend only based on instances of objects. But perhaps the above example is close enough (it's about the same number of characters to type anyway :) )