0

Consider the following enum:

enum Color 
{
  None = 0,
  Yellow = 1,
  Green = 2,
  Blue = 4
}
var enumType = typeof(Color);

var number = (int)(Color.Yellow | Color.Green);
// number equals to 3

Now I want the reverse of the above operation. I wanna know what enumerations lead to the number 3. like:

string[] names = GetEnumNames(enumType, 3);
// It should return an array { "Yellow", "Green" }

I have tried Enum.ToObject and I know that it returns the Enum with "Yellow" and "Green" in it. But how can I get the list of names?

Note: Just to mention, I only know the type of the Enum at runtime.

morty
  • 50
  • 6
  • How's `Yellow` and `Green` connected with `3`?? – Claudio Redi Aug 01 '20 at 15:10
  • Enum.GetNames can help you – vivek nuna Aug 01 '20 at 15:14
  • @ClaudioRedi 3 is the integer representing the bitwise operation on "Yellow" and "Green" like: `var number = (int)(Color.Yellow | Color.Green)` and the `number` is `3`. – morty Aug 01 '20 at 15:15
  • 1
    Does this answer your question? [How to iterate over values of an Enum having flags?](https://stackoverflow.com/questions/4171140/how-to-iterate-over-values-of-an-enum-having-flags) – Phil Ross Aug 01 '20 at 16:02
  • @PhilRoss I ended up using the link to the answer you sent. – morty Aug 01 '20 at 16:35
  • Don't forget to add the `FlagsAttribute` to your enum. It plays a part in generating string representation and parsing. I think that the HasFlag method at one point relied on its existence, though that doesn't appear to be the case now despite what the docs say – pinkfloydx33 Aug 01 '20 at 16:59

6 Answers6

1

You can use Enum.GetValues() to get all the values and then filter to find those that match:

IEnumerable<string> GetEnumNames<T>(int value)
{
    return Enum.GetValues(typeof(T))
        .Cast<int>()
        .Where(i => i != 0 && (i & value) == i)
        .Cast<T>()
        .Select(i => i.ToString()); 
}

GetEnumNames<Color>(3); // => {"Yellow", "Green"}
Phil Ross
  • 23,417
  • 9
  • 67
  • 75
1

You need to use [Flags] with enum.

[Flags]
public enum Color 
{
  None = 0,
  Yellow = 1,
  Green = 2,
  Blue = 4
}

var twoOrThree = Color.Green | Color.Blue;
Console.WriteLine(twoOrThree.ToString());  

It will print Green, Blue

vivek nuna
  • 12,695
  • 7
  • 48
  • 123
  • ToString() prints them both even without [Flags], but getting the names directly seems to different – morty Aug 01 '20 at 20:02
1

Here's another approach similar to what Phil Ross posted, but using HasFlag:

Color colorCombo = Color.Yellow | Color.Green;

String[] colors = Enum.GetValues(typeof(Color)).Cast<Color>()
    .Where(i => i != 0 && colorCombo.HasFlag(i)).Select(i => i.ToString()).ToArray();

Console.WriteLine(String.Join(", ", colors));
Idle_Mind
  • 33,113
  • 3
  • 25
  • 33
0

Whilst you could get all the names into a string[] and then just reference that, Enums have a function that allows you to get the name associated with a value.

enum Color 
{
  None = 0,
  Yellow = 1,
  Green = 2,
  Blue = 4
}

public void SomeMethod() {
    string enumName = enum.GetName(typeof(Color), 2)
    // enumName = Green
}

MSDN has a good example on it as well

Rhys Wootton
  • 184
  • 8
  • Just test 3 instead of 2 and you'll get null – morty Aug 01 '20 at 15:47
  • All, didn't realise it was dealing with bitwise operations. The solution Phil Ross has put up works. I was just working on it but he beat me to it so I wont edit my answer. – Rhys Wootton Aug 01 '20 at 16:08
0

Using the Flags approach suggested by vivek nuna, you could cheat and do:

[Flags]
enum Color
{
    None = 0,
    Yellow = 1,
    Green = 2,
    Blue = 4
}

static void Main(string[] args)
{           
    var colorCombo = Color.Yellow | Color.Green;
    var colors = HasFlags(colorCombo);
    Console.WriteLine(String.Join(", ", colors));

    Console.Write("Press Enter to Quit");
    Console.ReadLine();
}

public static IEnumerable<String> HasFlags(Enum value)
{
    return value.ToString().Split(",".ToCharArray()).Select(v => v.Trim());
}
Idle_Mind
  • 33,113
  • 3
  • 25
  • 33
-1

To get the items of enum, type

string[] enums = Enum.GetNames(typeof(myEnum))
Tavershima
  • 141
  • 8