12

I know how to loop through enum list of properties, but how would I loop through all "selected" enum properties? For example, if one did Prop1 | Prop2 against public enum Foo { Prop1; Prop2; Prop3 }, how would I achieve this?

This is what I have now:

var values = Enum.GetValues(typeof(FileStatus)).Cast<FileStatus>();
foreach (var value in values)
{
}

It loops through all enum properties, but I'd like to loop only the ones that were "selected".

Update: [Flags] attribute was set.

Update 2: The enum contains a large number of properties, I can't and won't type/hardcode a single property check, instead I want to dynamically loop through each of them and check if my enum instance Bar contains the looped item set.

Tower
  • 98,741
  • 129
  • 357
  • 507
  • Did you stick the FlagsAttribute on the enum? – scottheckel Apr 24 '12 at 17:59
  • @Hexxagonal: Doesn't matter. However, explicitly assigning values matters a whole lot. – Ben Voigt Apr 24 '12 at 18:00
  • @Hexxagonal That's really more optional than anything. The enums may or may not each be powers of two. Whether or not the flags att. is set *should* matter, but really it doesn't. – Servy Apr 24 '12 at 18:00
  • This question is being discussed on [Meta](http://meta.stackoverflow.com/questions/325659/closing-for-duplicate). – Glorfindel Jun 07 '16 at 14:24

5 Answers5

28

How about the following:

FileStatus status = FileStatus.New|FileStatus.Amazing;

foreach (FileStatus x in Enum.GetValues(typeof(FileStatus)))
{
    if (status.HasFlag(x)) Console.WriteLine("{0} set", x);
}

Or in one fell LINQ swoop:

var flags = Enum.GetValues(typeof(FileStatus))
                .Cast<FileStatus>()
                .Where(s => status.HasFlag(s));
user7116
  • 63,008
  • 17
  • 141
  • 172
4
[Flags]
public enum Foo
{
    Prop1 = 1,
    Prop2 = 1 << 1,
    Prop3 = 1 << 2
}

public static class FooExtensions
{
    private static readonly Foo[] values = (Foo[])Enum.GetValues(typeof(Foo));

    public static IEnumerable<Foo> GetComponents(this Foo value)
    {
        return values.Where(v => (v & value) != 0);
    }
}

public static class Program
{
    public static void Main(string[] args)
    {
        var foo = Foo.Prop1 | Foo.Prop3;

        var components = foo.GetComponents().ToArray();
    }
}
Stipo
  • 4,566
  • 1
  • 21
  • 37
3

Assuming you have this set as a bitmask, then simply "and"-ing the values would determine which are selected.

 SomeEnum bitmask = value;

 if(bitmask & SomeEnum.Value1 > 0)
    // SomeEnum.Value1 was set
Tejs
  • 40,736
  • 10
  • 68
  • 86
1
FileStatus someValue = ...;
var selectedValues = new List<FileStatus>();
var allValues = Enum.GetValues(typeof(FileStatus)).Cast<FileStatus>();
foreach (var value in allValues )
{
  if(someValue & value != 0)//note bitwise AND, not logical AND.
  {
     selectedValues.Add(value);
     //this value is selected.  You can stick it in a List or do whatever with it.
  }
}
Servy
  • 202,030
  • 26
  • 332
  • 449
0

You would need to mark the enum with Flags attribute. To get the values you can use yourObject.EnumProperty.HasFlag method, for example:

class Program 
{
    [Flags]
    public enum Bar { Prop1, Prop2, Prop3 }

    public class Foo
    {
        public Bar SelectedBar { get; set; }
    }

    static void Main(string[] args)
    {
        var foo = new Foo();
        foo.SelectedBar = Bar.Prop1 | Bar.Prop2;

        foo.SelectedBar.HasFlag(Bar.Prop1); //true
        foo.SelectedBar.HasFlag(Bar.Prop2); //true
        foo.SelectedBar.HasFlag(Bar.Prop3); //false
    }
}
oleksii
  • 35,458
  • 16
  • 93
  • 163