Question

In vs2008, is it possible to write an extension methods which would apply to any enumeration.

I know you can write extension methods against a specific enumeration, but I want to be able to every enumeration using a single extension method. Is this possible?

Was it helpful?

Solution

Yes, just code against the base Enum type, e.g.

public static void Something(this Enum e)
{
    // code here
}

The down-side is you'll probably end up doing some quite nasty stuff like finding the real base type using Enum.GetUnderlyingType, casting, and going down different branches depending on what the base type of the enum is, but you can find some good uses for it (e.g. we have IsOneOf and IsCombinationOf methods that apply to all enums).

PS: Remember when writing the method that, although ill advised, you can use float and double as the base types for enums so you'll need some special cases for those as well as unsigned values.

OTHER TIPS

Yes, you can. The target extenstion type is of type Enum. In C#, this would be done as:

public static void EnumExtension(this Enum e)
{
}

or like this in VB:

<Extension()> _
Public Sub EnumExtension(ByVal s As Enum)
End Sub

FYI Here is a great example of an Enum Extension method that I have been able to use. It implements a case insensitive TryParse() function for enums:

public static class ExtensionMethods
{
    public static bool TryParse<T>(this Enum theEnum, string strType, 
        out T result)
    {
        string strTypeFixed = strType.Replace(' ', '_');
        if (Enum.IsDefined(typeof(T), strTypeFixed))
        {
            result = (T)Enum.Parse(typeof(T), strTypeFixed, true);
            return true;
        }
        else
        {
            foreach (string value in Enum.GetNames(typeof(T)))
            {
                if (value.Equals(strTypeFixed, 
                    StringComparison.OrdinalIgnoreCase))
                {
                    result = (T)Enum.Parse(typeof(T), value);
                    return true;
                }
            }
            result = default(T);
            return false;
        }
    }
}

You would use it in the following manner:

public enum TestEnum
{
    A,
    B,
    C
}

public void TestMethod(string StringOfEnum)
{
    TestEnum myEnum;
    myEnum.TryParse(StringOfEnum, out myEnum);
}

Here are the two sites that I visited to help come up with this code:

Case Insensitive TryParse for Enums

Extension methods for Enums

Here's another example - also nicer IMHO than having to create and initialize a temp variable.

public static class ExtensionMethods 
{
    public static void ForEach(this Enum enumType, Action<Enum> action)
    {
        foreach (var type in Enum.GetValues(enumType.GetType()))
        {
            action((Enum)type);
        }
    }
}

public enum TestEnum { A,B,C } 
public void TestMethod() 
{
    default(TestEnum).ForEach(Console.WriteLine); 
} 

You can also implement conversion method as follows:

public static class Extensions
{
    public static ConvertType Convert<ConvertType>(this Enum e)
    {
        object o = null;
        Type type = typeof(ConvertType);

        if (type == typeof(int))
        {
            o = Convert.ToInt32(e);
        }
        else if (type == typeof(long))
        {
            o = Convert.ToInt64(e);
        }
        else if (type == typeof(short))
        {
            o = Convert.ToInt16(e);
        }
        else
        {
            o = Convert.ToString(e);
        }

        return (ConvertType)o;
    }
}

Here is an example usage:

int a = MyEnum.A.Convert<int>();

Sometimes there is a need to convert from one enum to another, based on the name or value of the enum. Here is how it can be done nicely with extension methods:

enum Enum1 { One = 1, Two = 2, Three = 3 };
enum Enum2 { Due = 2, Uno = 1 };
enum Enum3 { Two, One };

Enum2 e2 = Enum1.One.ConvertByValue<Enum2>();
Enum3 e3 = Enum1.One.ConvertByName<Enum3>();
Enum3 x2 = Enum1.Three.ConvertByValue<Enum3>();

public static class EnumConversionExtensions
{
    public static T ConvertByName<T>(this Enum value)
    {
        return (T)Enum.Parse(typeof(T), Enum.GetName(value.GetType(), value));
    }

    public static T ConvertByValue<T>(this Enum value)
    {
        return (T)((dynamic)((int)((object)value)));
    }
}

Another example of making Enum extension - but this time it returns the input enum type.

public static IEnumerable<T> toElementsCollection<T>(this T value) where T : struct, IConvertible
    {
        if (typeof(T).IsEnum == false) throw new Exception("typeof(T).IsEnum == false");

        return Enum.GetValues(typeof(T)).Cast<T>();
    }

Example of usage:

public enum TestEnum { A,B,C };

TestEnum.A.toElementsCollection();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top