views:

463

answers:

4

Hi,

I was wondering whether or not I can extend the Enum type in C# to implement my custom Enum.GetValues(type) and call it like Enum.GetMyCustomValues(type)

I am trying to implement something like this:

public static bool IsFlagSet<T>(this T value, T flag) where T : Enum
{
    return (value & flag) != (T)0;
}

but it cannot be done... any work arounds I can do? Cheers

A: 

I think you may be looking for extension methods for enums. Here's a starting link: http://pietschsoft.com/post/2008/07/C-Enhance-Enums-using-Extension-Methods.aspx

FrustratedWithFormsDesigner
Not really what I am looking for, more interested in extending the Enum.SomeMethod() instead of MyCustomEnum.SomeMethod()
Titan
+2  A: 

Extensions work on instances, not for creating static methods. You can extend the base Enum using public static void MyExtensions(this Enum value). But this would still only create methods on Enum instances you create. The only way to add static methods like you're talking about externally for a class is if the class is a partial class.

Edit: to do something like you want I wrote the following

public static bool IsFlagSet<T>(this Enum value, Enum flag)
{
    if (!typeof(T).IsEnum) throw new ArgumentException();
    if (value == flag) return true;
    return ((int)Enum.Parse(typeof(T), value.ToString()) &
        (int)Enum.Parse(typeof(T), flag.ToString())) != 0;
}

*warning, this method needs to be thought out more prior to use, I'm hoping there is a better way to do it.

Yuriy Faktorovich
There is not need for the generic constraint
shf301
A: 

Here's test best I could think of. Remember that enums could be based on 64 bit ints:

 public static bool IsFlagSet(this Enum value, Enum flag)
 {
     if (Type.GetTypeHandle(value).Value != Type.GetTypeHandle(flag).Value)
         throw new ArgumentException();
     return (Convert.ToInt64(value) & Convert.ToInt64(flag)) != 0L;
 }
shf301
A: 

And one more example.

    public static bool Includes<T>(this T value, T flag) where T : struct, IConvertible
    {
        var val = value.ToUInt32(null);
        var fl = flag.ToUInt32(null);
        return (val & fl) == fl;
    }

And the usage.

SomeEnum val = SomeEnum.One;
bool isOne = val.Includes(SomeEnum.One); // == true
bool isTwo = val.Includes(SomeEnum.Two); // == false
Vasiliy Borovyak