Enumeration extension methods
Asked Answered
W

7

54

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?

Woodworth answered 9/11, 2008 at 22:31 Comment(1)
Does this answer your question? Extension method on enumeration, not instance of enumerationDorcy
W
81

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.

Witt answered 9/11, 2008 at 22:34 Comment(5)
The examples you gave are exactly what I want to do, even the same name. :)Woodworth
@Greg: In which language can you use float and double as the underlying type for an enum? You can't in C# - you get error CS1008: Type byte, sbyte, short, ushort, int, uint, long, or ulong expectedNorth
The only language I know of that supports it is CIL. I haven't actually tried it out to prove it because it seems like a generally bad idea, but see Rico's comment near the bottom here: en.csharp-online.net/…Witt
@Luis - No, you need C# 3.0 syntax for extension methods, which isn't supported in VS2005.Witt
@GregBeech: Are you able to help with this post? https://mcmap.net/q/83137/-generic-enum-to-selectlist-extension-method/175893Dekow
D
18

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
Department answered 9/11, 2008 at 22:40 Comment(0)
C
18

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

Calpe answered 18/6, 2009 at 0:1 Comment(1)
Just as a footnote, from .net 4 onwards there's Enum.TryParse takes an overload to specify case sensitivity: msdn.microsoft.com/en-us/library/dd991317%28v=vs.100%29.aspxVeradis
D
9

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); 
} 
Distracted answered 12/1, 2012 at 5:29 Comment(1)
You are still creating a temporary instance of the enum in default(TestEnum), albeit one that is anonymous and immediately up for garbage collection. It's worth pointing out that extension methods simply do not work without an instance of what is being extended, so the closest that we can get is to instantiate the Type of the enum itself and have an extension method off that type. See #2422613 for an interesting way of accomplishing this.Bentinck
S
4

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>();
Smallscale answered 25/6, 2012 at 14:22 Comment(1)
I think every Enum implements IConvertible anyway.Filberto
T
2

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)));
    }
}
Tutor answered 31/10, 2013 at 13:33 Comment(0)
S
1

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();
Sharmainesharman answered 20/7, 2015 at 22:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.