-1

I have this enum:

[Flags]
public enum MyEnum
{
    None = 0,
    ProductOne = 1,
    ProductTwo = 2,
    AllProducts = ProductOne | ProductTwo
}

I want to get the names (is names the right way to reference these?) of each item in the object that is passed in. I have this method to do that.

private string[] MyMethod(MyEnum myEnum)
{
    if (myEnum == MyEnum.AllProducts)
    {
        return new string[] { MyEnum.ProductOne.ToString(), MyEnum.ProductTwo.ToString() };
    }
    else if (myEnum == MyEnum.None)
    {
        return new string[0];
    }

    return new string[] { myEnum.ToString() };
}

My question is, is there a way to somehow iterate through the values in the bitwise enum (MyEnum.AllProducts) and put them into a string array, compared to the way I'm doing above?

Thanks.

Teste Account
  • 903
  • 6
  • 19
mouldycurryness
  • 85
  • 1
  • 11
  • 1
    You should check the [`Enum.GetNames(typeof(MyEnum))`](https://docs.microsoft.com/en-us/dotnet/api/system.enum.getnames?view=netframework-4.7.2) and `Enum.GetValues()` methods – Jeroen van Langen Apr 02 '19 at 11:02
  • 3
    Possible duplicate of [How to loop through all enum values in C#?](https://stackoverflow.com/questions/972307/how-to-loop-through-all-enum-values-in-c) – Sinatr Apr 02 '19 at 11:06
  • Instead of saying *"compared to the way I'm doing above"* it would be better to explain what are you doing. It doesn't look like enumerating, rather you return bits which are set in parameter as array of names. – Sinatr Apr 02 '19 at 11:15
  • Here is the code which handles `enum.ToString()` when `enum` is decorated with `[Flags]`: https://referencesource.microsoft.com/#mscorlib/system/enum.cs,154 . You can copy that, but make `retval` a list instead of a `StringBuilder`. This handles some of the edge cases that the accepted answer doesn't, if you care about those. – canton7 Apr 02 '19 at 11:29
  • Possible duplicate of [How do I enumerate an enum in C#?](https://stackoverflow.com/questions/105372/how-do-i-enumerate-an-enum-in-c) – Ian Kemp Apr 02 '19 at 11:29

1 Answers1

3

You can use following code:

var values = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>();

var result = values.
               Where(x => x != MyEnum.None).
               Where(x => (myEnum & x) == x).
               Select(x => x.ToString()).
               ToArray();
return result.Length == 0 ? 
       new[] {MyEnum.None.ToString()} : 
       result;

And the explanations:

  1. Iterate through all enum values
  2. Except the enum value which equals to zero (Where(x => x != MyEnum.None).)
  3. Take enum value which bitwise is good (Where(x => (myEnum & x) == x).)
  4. Convert it to array (Select(x => x.ToString()).ToArray();)
  5. If array is empty return None (because enum doesn't equal to anything else), otherwise return an array
Piotr Stapp
  • 18,130
  • 10
  • 63
  • 104
  • 1
    This will also return AllProducts value if it is set. While not explicitly stated, I think this should be filtered out as well (at your second step). Would be most concise if it is defined in the enum and filtered using `~0`, but that may be thinking too far ahead (in case products get added). – Jeroen V Apr 02 '19 at 11:37