3

I have this flag enum:

public enum DataAccessPoliceis
{
      None = 0,
      A = 1,
      B = 2,
      C = 4, 
      D = 8, 
      E = B | C | D, // 14
      All = A | E // 15
}

I want to get int value (or list of int values for complex enum item) from int value:

int x = 9; // enum items => D | A
List<int> lstEnumValues = ???
// after this line ...
// lstEnumValues = { 1, 8 }
// and for x = 15
// lstEnumValues = { 1, 2, 4, 8, 14, 15 }

What's your solution for this question?

halfer
  • 19,824
  • 17
  • 99
  • 186
Sayed Abolfazl Fatemi
  • 3,678
  • 3
  • 36
  • 48
  • This line is incorrect: `int x = 9; // enum items => D | E`. The result is `14` or `D` because the `| ` is bitwise OR. – dyatchenko Feb 28 '15 at 08:32

5 Answers5

8

Use can use the class Enum and the GetValues method. Try it Like this:

var lstEnumValues = new List<int>(Enum.GetValues(typeof(DataAccessPolicies)).Cast<int>());

The output is:

Output result

Hope this helps.

HerrimanCoder
  • 6,835
  • 24
  • 78
  • 158
dyatchenko
  • 2,283
  • 3
  • 22
  • 32
  • Thanks for your replay. It's useful, but i need to get Value of enums by pass int value: // for x = 15 // lstEnumValues = { 1, 2, 4, 8, 14, 15 } or // for x = 14 // lstEnumValues = { 2, 4, 8, 14 } – Sayed Abolfazl Fatemi Feb 28 '15 at 07:45
  • 2
    @SayedAbolfazlFatemi - This answer has done the heavy lifting for you. You just need to add a `.Where(x => x != 0 && (x & 15) == x)` after the cast. – Enigmativity Feb 28 '15 at 08:01
5

Answer of my question:

var lstEnumValues = new List<int>Enum.GetValues(typeof(DataAccessPoliceis)).Cast<int>())
.Where(enumValue => enumValue != 0 && (enumValue & x) == enumValue).ToList();

@dyatchenko and @Enigmativity thank you for your responses.

Sayed Abolfazl Fatemi
  • 3,678
  • 3
  • 36
  • 48
1

Try:

var lstEnumValues =
    ((DataAccessPoliceis[])(Enum.GetValues(typeof(DataAccessPoliceis))))
    .Where(v => v.HasFlag(x))
    .Select(v => (int)v)  // omit if enum values are OK
    .ToList();            // omit if List<> not needed
Jeppe Stig Nielsen
  • 60,409
  • 11
  • 110
  • 181
1

For these scenarios I prefer using extension methods.

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;
}

Usage:

 var lstEnumValues = flagEnum.ToEnumerable().Select(x => Convert.ToInt32(x)).ToList();  
Nabeel
  • 31
  • 6
0

Yet another approach:

As flags are only combinations of exponentiated numbers to base 2 and every natural number has exactly one representation in the binary number-system, it is actually sufficient to consider only the binary representation (not the enum itself). After the conversion to the binary representation, there is only to convert all places with a "1" back to the decimal-system (and to omit the zeros) and to output in form of a list.

With a little help from LINQ this can be written like this:

int value = 9;

//convert int into a string of the the binary representation
string binary = Convert.ToString(value, 2);

var listOfInts = binary

    //convert each binary digit back to a decimal
    .Select((v, i) => Int32.Parse(v.ToString()) * Math.Pow(2, binary.Length-i-1))   
    
    //filter decimal numbers that are based on the "1" in binary representation
    .Where(x => x > 0)  

     //you want the integers in ascending order
    .OrderBy(x => x);   
Grimm
  • 690
  • 8
  • 17