views:

3769

answers:

4

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?

+5  A: 

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.

Greg Beech
The examples you gave are exactly what I want to do, even the same name. :)
Eric Haskins
@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 expected
Jon Skeet
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: http://en.csharp-online.net/.NET_Type_Design_Guidelines%E2%80%94Enum_Design
Greg Beech
Does this work for VS2005?
Luis Filipe
@Luis - No, you need C# 3.0 syntax for extension methods, which isn't supported in VS2005.
Greg Beech
+6  A: 

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
Scott Dorman
+1  A: 

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:

publi 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

Michael La Voie
A: 

I do the above but get a "use of unassigned local variable" compiler error on "myEnum".... Do I need to ignore certain error types for this to work??

In fact, to make this code:

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

compile it needs to be changed to:

public enum TestEnum
{    
A,B,C
}
public void TestMethod(string StringOfEnum)
{
    TestEnum myEnum = default(TestEnum);
    myEnum.TryParse(StringOfEnum, out myEnum);
}

No other example I've seen shows this. Have I got a setting wrong somewhere?