How to iterate over values of an Enum having flags?

C#EnumsEnum Flags

C# Problem Overview


If I have a variable holding a flags enum, can I somehow iterate over the single-bit values in that specific variable? Or do I have to use Enum.GetValues to iterate over the entire enum and check which ones are set?

C# Solutions


Solution 1 - C#

static IEnumerable<Enum> GetFlags(Enum input)
{
    foreach (Enum value in Enum.GetValues(input.GetType()))
        if (input.HasFlag(value))
            yield return value;
}

Solution 2 - C#

Here is a Linq solution to the problem.

public static IEnumerable<Enum> GetFlags(this Enum e)
{
      return Enum.GetValues(e.GetType()).Cast<Enum>().Where(e.HasFlag);
}

Solution 3 - C#

There aren't any builtin methods to get each component as far as I know. But here's one way you can get them:

[Flags]
enum Items
{
    None = 0x0,
    Foo  = 0x1,
    Bar  = 0x2,
    Baz  = 0x4,
    Boo  = 0x6,
}

var value = Items.Foo | Items.Bar;
var values = value.ToString()
                  .Split(new[] { ", " }, StringSplitOptions.None)
                  .Select(v => (Items)Enum.Parse(typeof(Items), v));

// This method will always end up with the most applicable values
value = Items.Bar | Items.Baz;
values = value.ToString()
              .Split(new[] { ", " }, StringSplitOptions.None)
              .Select(v => (Items)Enum.Parse(typeof(Items), v)); // Boo


I adapted what Enum does internally to generate the string to instead return the flags. You can look at the code in reflector and should be more or less equivalent. Works well for general use cases where there are values which contain multiple bits.

static class EnumExtensions
{
    public static IEnumerable<Enum> GetFlags(this Enum value)
    {
        return GetFlags(value, Enum.GetValues(value.GetType()).Cast<Enum>().ToArray());
    }

    public static IEnumerable<Enum> GetIndividualFlags(this Enum value)
    {
        return GetFlags(value, GetFlagValues(value.GetType()).ToArray());
    }

    private static IEnumerable<Enum> GetFlags(Enum value, Enum[] values)
    {
        ulong bits = Convert.ToUInt64(value);
        List<Enum> results = new List<Enum>();
        for (int i = values.Length - 1; i >= 0; i--)
        {
            ulong mask = Convert.ToUInt64(values[i]);
            if (i == 0 && mask == 0L)
                break;
            if ((bits & mask) == mask)
            {
                results.Add(values[i]);
                bits -= mask;
            }
        }
        if (bits != 0L)
            return Enumerable.Empty<Enum>();
        if (Convert.ToUInt64(value) != 0L)
            return results.Reverse<Enum>();
        if (bits == Convert.ToUInt64(value) && values.Length > 0 && Convert.ToUInt64(values[0]) == 0L)
            return values.Take(1);
        return Enumerable.Empty<Enum>();
    }

    private static IEnumerable<Enum> GetFlagValues(Type enumType)
    {
        ulong flag = 0x1;
        foreach (var value in Enum.GetValues(enumType).Cast<Enum>())
        {
            ulong bits = Convert.ToUInt64(value);
            if (bits == 0L)
                //yield return value;
                continue; // skip the zero value
            while (flag < bits) flag <<= 1;
            if (flag == bits)
                yield return value;
        }
    }
}

The extension method GetIndividualFlags() gets all the individual flags for a type. So values containing multiple bits are left out.

var value = Items.Bar | Items.Baz;
value.GetFlags();           // Boo
value.GetIndividualFlags(); // Bar, Baz

Solution 4 - C#

Coming back at this a few years later, with a bit more experience, my ultimate answer for single-bit values only, moving from lowest bit to highest bit, is a slight variant of Jeff Mercado's inner routine:

public static IEnumerable<Enum> GetUniqueFlags(this Enum flags)
{
    ulong flag = 1;
    foreach (var value in Enum.GetValues(flags.GetType()).Cast<Enum>())
    {
        ulong bits = Convert.ToUInt64(value);
        while (flag < bits)
        {
            flag <<= 1;
        }

        if (flag == bits && flags.HasFlag(value))
        {
            yield return value;
        }
    }
}

It seems to work, and despite my objections of some years ago, I use HasFlag here, since it's far more legible than using bitwise comparisons and the speed difference is insignificant for anything I'll be doing. (It's entirely possible they've improved the speed of HasFlags since then anyway, for all I know...I haven't tested.)

Solution 5 - C#

Going off of @Greg's method, but adding a new feature from C# 7.3, the Enum constraint:

public static IEnumerable<T> GetUniqueFlags<T>(this T flags)
    where T : Enum    // New constraint for C# 7.3
{
    foreach (Enum value in Enum.GetValues(flags.GetType()))
        if (flags.HasFlag(value))
            yield return (T)value;
}

The new constraint allows this to be an extension method, without having to cast through (int)(object)e, and I can use the HasFlag method and cast directly to T from value.

C# 7.3 also added constraints to for delegates and unmanaged.

Solution 6 - C#

+1 for the answer provided by @RobinHood70. I found that a generic version of the method was convenient for me.

public static IEnumerable<T> GetUniqueFlags<T>(this Enum flags)
{
    if (!typeof(T).IsEnum)
        throw new ArgumentException("The generic type parameter must be an Enum.");

    if (flags.GetType() != typeof(T))
        throw new ArgumentException("The generic type parameter does not match the target type.");

    ulong flag = 1;
    foreach (var value in Enum.GetValues(flags.GetType()).Cast<T>())
    {
        ulong bits = Convert.ToUInt64(value);
        while (flag < bits)
        {
            flag <<= 1;
        }

        if (flag == bits && flags.HasFlag(value as Enum))
        {
            yield return value;
        }
    }
}

EDIT And +1 for @AustinWBryan for bringing C# 7.3 into the solution space.

public static IEnumerable<T> GetUniqueFlags<T>(this T flags) where T : Enum
{
    ulong flag = 1;
    foreach (var value in Enum.GetValues(flags.GetType()).Cast<T>())
    {
        ulong bits = Convert.ToUInt64(value);
        while (flag < bits)
        {
            flag <<= 1;
        }

        if (flag == bits && flags.HasFlag(value as Enum))
        {
            yield return value;
        }
    }
}

Solution 7 - C#

Extension method using the new Enum constraint and generics to prevent casting:

public static class EnumExtensions
{
    public static T[] GetFlags<T>(this T flagsEnumValue) where T : Enum
    {
        return Enum
            .GetValues(typeof(T))
            .Cast<T>()
            .Where(e => flagsEnumValue.HasFlag(e))
            .ToArray();
    }
}

Solution 8 - C#

What I did was change my approach, instead of typing the input parameter of the method as the enum type, I typed it as an array of the enum type (MyEnum[] myEnums), this way I just iterate through the array with a switch statement inside the loop.

Solution 9 - C#

Continuing in my efforts to make the code shorter, this is my latest version of the routine. (I'm the OP...long story.) As discussed previously, this ignores None and multi-bit values.

Note that this uses an Enum constraint and a var pattern, so will require at least C# 7.3.

public static IEnumerable<T> GetUniqueFlags<T>(this T value)
	where T : Enum
{
	var valueLong = Convert.ToUInt64(value, CultureInfo.InvariantCulture);
	foreach (var enumValue in value.GetType().GetEnumValues())
	{
		if (
			enumValue is T flag // cast enumValue to T
			&& Convert.ToUInt64(flag, CultureInfo.InvariantCulture) is var bitValue // convert flag to ulong
			&& (bitValue & (bitValue - 1)) == 0 // is this a single-bit value?
			&& (valueLong & bitValue) != 0 // is the bit set?
		   )
		{
			yield return flag;
		}
	}
}

Solution 10 - C#

You dont need to iterate all values. just check your specific flags like so:

if((myVar & FlagsEnum.Flag1) == FlagsEnum.Flag1)
{
//do something...
}

or (as pstrjds said in comments) you can check for use it like:

if(myVar.HasFlag(FlagsEnum.Flag1))
{
//do something...
}

Solution 11 - C#

Wasn't satisfied with the answers above, although they were the start.

After piecing together some different sources here:
Previous poster in this thread's SO QnA
Code Project Enum Flags Check Post
Great Enum<T> Utility

I created this so let me know what you think.
Parameters:
bool checkZero: tells it to allow 0 as a flag value. By default input = 0 returns empty.
bool checkFlags: tells it to check whether the Enum is decorated w/ the [Flags] attribute.
PS. I don't have time right now to figure out the checkCombinators = false alg which will force it to ignore any enum values which are combinations of bits.

    public static IEnumerable<TEnum> GetFlags<TEnum>(this TEnum input, bool checkZero = false, bool checkFlags = true, bool checkCombinators = true)
    {
        Type enumType = typeof(TEnum);
        if (!enumType.IsEnum)
            yield break;

        ulong setBits = Convert.ToUInt64(input);
        // if no flags are set, return empty
        if (!checkZero && (0 == setBits))
            yield break;

        // if it's not a flag enum, return empty
        if (checkFlags && !input.GetType().IsDefined(typeof(FlagsAttribute), false))
            yield break;

        if (checkCombinators)
        {
            // check each enum value mask if it is in input bits
            foreach (TEnum value in Enum<TEnum>.GetValues())
            {
                ulong valMask = Convert.ToUInt64(value);

                if ((setBits & valMask) == valMask)
                    yield return value;
            }
        }
        else
        {
            // check each enum value mask if it is in input bits
            foreach (TEnum value in Enum <TEnum>.GetValues())
            {
                ulong valMask = Convert.ToUInt64(value);

                if ((setBits & valMask) == valMask)
                    yield return value;
            }
        }

    }

This makes use of the Helper Class Enum<T> found here that I updated to use yield return for GetValues:

public static class Enum<TEnum>
{
    public static TEnum Parse(string value)
    {
        return (TEnum)Enum.Parse(typeof(TEnum), value);
    }

    public static IEnumerable<TEnum> GetValues()   
    {
        foreach (object value in Enum.GetValues(typeof(TEnum)))
            yield return ((TEnum)value);
    }
}  

Finally, here's a example of using it:

    private List<CountType> GetCountTypes(CountType countTypes)
    {
        List<CountType> cts = new List<CountType>();

        foreach (var ct in countTypes.GetFlags())
            cts.Add(ct);

        return cts;
    }

Solution 12 - C#

Building upon Greg's answer above, this also takes care of the case where you have a value 0 in your enum, such as None = 0. In which case, it should not iterate over that value.

public static IEnumerable<Enum> ToEnumerable(this Enum input)
{
    foreach (Enum value in Enum.GetValues(input.GetType()))
        if (input.HasFlag(value) && Convert.ToInt64(value) != 0)
            yield return value;
}

Would anyone know how to improve upon this even further so that it can handle the case where all flags in the enum are set in a super smart way that could handle all underlying enum type and the case of All = ~0 and All = EnumValue1 | EnumValue2 | EnumValue3 | ...

Solution 13 - C#

You can use an Iterator from the Enum. Starting from the MSDN code:

public class DaysOfTheWeek : System.Collections.IEnumerable
{
    int[] dayflag = { 1, 2, 4, 8, 16, 32, 64 };
    string[] days = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
    public string value { get; set; }

    public System.Collections.IEnumerator GetEnumerator()
    {
        for (int i = 0; i < days.Length; i++)
        {
            if value >> i & 1 == dayflag[i] {
                yield return days[i];
            }
        }
    }
}

It's not tested, so if I made a mistake feel free to call me out. (obviously it's not re-entrant.) You'd have to assign value beforehand, or break it out into another function that uses enum.dayflag and enum.days. You might be able to go somewhere with the outline.

Solution 14 - C#

Here's yet another C# 7.3 solution using Linq

public static class FlagEnumExtensions
{
    public static IEnumerable<T> GetFlags<T>(this T en) where T : struct, Enum
    {
        return Enum.GetValues<T>().Where(member => en.HasFlag(member));
    }
}

Solution 15 - C#

It could be aswell as the following code:

public static string GetEnumString(MyEnum inEnumValue)
{
    StringBuilder sb = new StringBuilder();

    foreach (MyEnum e in Enum.GetValues(typeof(MyEnum )))
    {
        if ((e & inEnumValue) != 0)
        {
           sb.Append(e.ToString());
           sb.Append(", ");
        }
    }

   return sb.ToString().Trim().TrimEnd(',');
}

It goes inside if only when the enum value is contained on the value

Solution 16 - C#

All the answers work well with simple flags, you're probably going to get into issues when flags are combined.

[Flags]
enum Food
{
  None=0
  Bread=1,
  Pasta=2,
  Apples=4,
  Banana=8,
  WithGluten=Bread|Pasta,
  Fruits = Apples | Banana,
}

probably need to add a check to test if the enum value it self is a combination. You'd probably need something like posted here by Henk van Boeijen to cover your requirement (you need to scroll down a bit)

Solution 17 - C#

When it comes to performance, which is important in game development, all solutions given are terrible because of garbage allocation and slow speed. This is a garbage free, over 100 times faster solution than accepted answer.

[Flags]
public enum PersonalTraits : short
{
    None = 1 << 0,
    Strength = 1 << 1,
    Agility = 1 << 2,
    Attack = 1 << 3,
    Defence = 1 << 4,
    Vitality = 1 << 5,
    Stamina = 1 << 6,
    Accuracy = 1 << 7,
    Perception = 1 << 8,
    Charisma = 1 << 9,
}
PersonalTraits athlete = PersonalTraits.Stamina | PersonalTraits.Strength;

for (short i = 0, value = 0; value <= (short)PersonalTraits.Charisma; i++, value = (short)(1 << i))
    if (((short)athlete & value) != 0)
       yield return (PersonalTraits)value;

Solution 18 - C#

You can do it directly by converting to int but you will loose type checking. I think the best way is use something similar to my proposition. It keep the proper type all the way. No conversion required. It is not perfect due to boxing which will add a little hit in performance.

Not perfect (boxing), but it does the job with no warning...

/// <summary>
/// Return an enumerators of input flag(s)
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static IEnumerable<T> GetFlags<T>(this T input)
{
    foreach (Enum value in Enum.GetValues(input.GetType()))
    {
        if ((int) (object) value != 0) // Just in case somebody has defined an enum with 0.
        {
            if (((Enum) (object) input).HasFlag(value))
                yield return (T) (object) value;
        }
    }
}

Usage:

    FileAttributes att = FileAttributes.Normal | FileAttributes.Compressed;
    foreach (FileAttributes fa in att.GetFlags())
    {
        ...
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser502255View Question on Stackoverflow
Solution 1 - C#GregView Answer on Stackoverflow
Solution 2 - C#agrittonView Answer on Stackoverflow
Solution 3 - C#Jeff MercadoView Answer on Stackoverflow
Solution 4 - C#user502255View Answer on Stackoverflow
Solution 5 - C#AustinWBryanView Answer on Stackoverflow
Solution 6 - C#Wallace KellyView Answer on Stackoverflow
Solution 7 - C#Saeb AminiView Answer on Stackoverflow
Solution 8 - C#Ragin'GeekView Answer on Stackoverflow
Solution 9 - C#RobinHood70View Answer on Stackoverflow
Solution 10 - C#Dr TJView Answer on Stackoverflow
Solution 11 - C#eudaimosView Answer on Stackoverflow
Solution 12 - C#Didier A.View Answer on Stackoverflow
Solution 13 - C#SilverbackNetView Answer on Stackoverflow
Solution 14 - C#PaperNickView Answer on Stackoverflow
Solution 15 - C#G. ManucciView Answer on Stackoverflow
Solution 16 - C#Walter VerhoevenView Answer on Stackoverflow
Solution 17 - C#BracketsView Answer on Stackoverflow
Solution 18 - C#Eric OuelletView Answer on Stackoverflow