Question

I have an enum that looks like this:

enum foo{
a=0,
b=1,
c=2,
d=4
}

Building the flag / bitmask is fine, but is it possible to do something like

int i = 3;
var bar =  Enum.Split(foo,i);

Resulting in something like

bar = foo[]{a, b,c};

Thanks.

Was it helpful?

Solution

Try the following

public static IEnumerable<T> Split<T>(int value) {
  foreach (object cur in Enum.GetValues(typeof(T))) {
    var number = (int)(object)(T)cur;
    if (0 != (number & value)) {
      yield return (T)cur;
    }
  }
}

With this you can now write

int i = 3;
IEnumerable<foo> e = Split<foo>(i);

Note: This only works on enum values which derive from int (the default setting). It's also not entirely type safe as T can't be constrained to only enum values (nothing to do about that though)

OTHER TIPS

You can use the FlagsAttribute on the enum and get lots of the functionality for free (no need to work at the bit level).

MSDN describes the attribute as:

Indicates that an enumeration can be treated as a bit field; that is, a set of flags.

The [FlagsAttribute] allows you to extract all of the valid values.

http://msdn.microsoft.com/en-us/library/system.flagsattribute.aspx

Try this:

TEnum[] EnumSplit<TEnum>(int mask)
{
    List<TEnum> values = new List<TEnum>();
    foreach(int enumValue in Enum.GetValues(typeof(TEnum)))
    {
        if(mask & enumValue == enumValue)
            values.Add((TEnum)enumValue);
    }
    return values.ToArray();
}

Call it like this:

var bar = EnumSplit<foo>(i);

Preferably, you want to change it to return IEnumerable<TEnum> instead of TEnum[].

You could do this with a method which pulls the values from the Enum you pass:

public static T[] EnumSplit<T>(int value) where T : struct
{
    // Simplified as Enum.GetValues will complain if T is not an enum
    // However, you should add a check to make sure T implements FlagAttribute
    return (from vv in Enum.GetValues(typeof(T))
            where ((int)vv & value) != 0
            select (T)vv).ToArray();;
}
    var flags = Enum.GetValues(typeof (/* YourEnumType */))
                  .Cast</* YourEnumType */>()
                  .Select(v => enumValue.HasFlag(v))
                  .ToArray();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top