soapergem
soapergem

Reputation: 10019

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?

Upvotes: 2

Views: 2359

Answers (2)

ShawnFeatherly
ShawnFeatherly

Reputation: 2638

You can rename your helper method to Enum<> to make it look like it's extending Enum.

/// <summary> Enum Extension Methods </summary>
/// <typeparam name="T"> type of Enum </typeparam>
public class Enum<T> where T : struct, IConvertible
{
    public static T Parse(string input)
    {
        return (T)Enum.Parse(typeof(T), input, true);
    }
}

Then use it the same way as the helper method the OP mentioned:

var result = Enum<StatusEnum>.Parse("Active");

This isn't an extension method. Yet, it shares one of the goals of extension methods. Naming a class close to Enum tries to help discoverability.

Upvotes: 0

Peter Duniho
Peter Duniho

Reputation: 70691

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 :) )

Upvotes: 5

Related Questions