Click here to Skip to main content
14,690,505 members
Please Sign up or sign in to vote.
4.60/5 (9 votes)
See more:
I have an enum with flags attribute. How to check if int is in enum. Enum.IsDefiend returns false if check for example two ored values from enum.
Thanks in advance.
#realJSOP 10-May-11 14:52pm
5 - Great question, btw.
Rick Shaub 10-May-11 15:08pm
I agree it made me have to think outside the box.

This is how to do it:

static bool IsIntInEnum(System.Type enumType, int value) {
   if (enumType == null) return false;
   if (!enumType.IsEnum) return false;
   var values = System.Enum.GetValues(enumType);
   if (values == null) return false;
   if (values.Length < 1) return false;
   foreach (object enumvalue in values)
       if (enumvalue is int) break; else return false;
   System.Predicate<int> predicate = (item) => { return (item & value) > 0; };
   return System.Array.Exists<int>((int[])values, predicate);

It is important to understand that the attribute System.FlagsAttribute only affects the string presentation of the value via ToString or string.Format. Also, with or without this attribute, enumeration members does not have to be powers of two. There are quite practical applications (in Windows API, for example) when the set of enumeration members represents the mixture of bit set values with, say, a set of consecutive values.

Rick Shaub 10-May-11 21:54pm
I don't think this solves the OP's problem.
Sergey Alexandrovich Kryukov 10-May-11 22:39pm
First, it's not yet complete. I have another variant, secondly -- arguments, please!
(I'll notify when it's done.)
Sergey Alexandrovich Kryukov 10-May-11 22:42pm
Now it's done.
As far as I can see, this is the only correct solution on this page. You can test it.
Rick Shaub 10-May-11 23:05pm
The OP wants to check if an int is bitwise OR of two or more flags, or a value in his enum. This solution will not do that. This type of iterative approach is going to be O(2^n) because you have to check all combinations of flags before declaring the result false. You could build a table and perform a binary search, which would be probably optimal timewise. Here's a simple test case:

public enum FlagEnum
eight = 8,
sixteen =16,
thirtytwo = 32

private void button1_Click(object sender, EventArgs e)
bool orly = IsIntInEnum(typeof(FlagEnum),(int)(|FlagEnum.thirtytwo));

Sergey Alexandrovich Kryukov 10-May-11 23:14pm
No, it won't, I agree. The question is formulated the way I'm not sure this is what is asked.

You see, FlagsAttribute has nothing to do with bitwise operations except presentation of the value by ToString. Moreover, enum members do not have to be the powers of 2. Perhaps this is the illusion of OP that it explains it. Until OP mentions explicitly a bit in a bit set, this is not either incorrectly formulated question or something what I did.

Finding if a bit is in enum is another simple task but I don't want to solve it until OP clear the question.

Anyway, thank you for this note, I'll modify the answer.
Rick Shaub 10-May-11 23:16pm
He states clearly; " Enum.IsDefiend returns false if check for example two ored values...". This answer was already accepted, what's the problem? I don't think you understand the complexity. It's not simply find if a bit is in an enum, it's finding if an int matches any of the combination of bitwise ORs. My approach would work regardless of power-of-twos or not. I only used powers of twos to clearly demonstrate the principle. And FlagsAttribute has everything to do with bitwise OR. That's it's only purpose, to treat an enumeration as a bit field.
Sergey Alexandrovich Kryukov 10-May-11 23:24pm
I got it. Answer updated.
I know you've already accepted an answer, but here's a more math-oriented way (more code, too):

bool IsFlagsValid(Type t, int value)
    bool valid = false;
    if (t.IsEnum)
        valid = true;
        int maxBit = Convert.ToInt32(Math.Pow(2, Math.Ceiling(Math.Log(value)/Math.Log(2)))) >> 2;
        int i = 1;
            if (0 != (value & (1 << i)))
                valid = (Enum.IsDefined(t, 1 << i));
                if (!valid)
        } while (maxBit > i);
    return valid;

Call it like this:

if (IsFlagsValid(MyFlagsEnum, 25))
    // do something if the value was valid
yesotaso 10-May-11 15:24pm
What if... (just a thought)
public enum psychoEnum
{ A = 0, B = 3, C = 4, D = 8 ... }
#realJSOP 10-May-11 15:33pm
For a Flags enum, 3 is not a valid ordinal, because if the enum value is set to 3, that means ordinals 1 and 2 are indicated. That's the way Flags enums work.
yesotaso 10-May-11 15:50pm
Well yes 3 is not valid but it just compiles and runs :) Though I'd never do such thing knowingly.
Sergey Alexandrovich Kryukov 10-May-11 20:05pm
3 is valid! FlagsAttribute only effect naming in ToString.
yesotaso 10-May-11 20:43pm
Yes sir, syntactically and semantically but not figuratively.
Edit: I mean it boils down to habits again. Use of powers of 2 - checking against "logical and" etc..
BobJanova 11-May-11 5:23am
It is valid:
enum SimpleExample { None = 0, Left = 1, Right = 2, Both = 3 }
Sergey Alexandrovich Kryukov 10-May-11 20:03pm
John, I think there are some problem with this solution. Are you sure you do not assume the enumeration members are not always the powers of 2? They don't have to be. Using math for finding a maximum is not very elegant.

Please see my solution based on GetValues, I think it's free of these problems.
Rick Shaub 11-May-11 9:38am
FYI from MSDN: "Guidelines for FlagsAttribute and Enum: ...
Define enumeration constants in powers of two, that is, 1, 2, 4, 8, and so on. This means the individual flags in combined enumeration constants do not overlap. ..."

This basically means that while it's possible to define non power of two Flags-decorated enums, it is not recommended.
Ankur\m/ 21-May-11 2:02am
I know it's old but...
I guess that comment was for SA. You clicked 'Add Comment' which will only notify the answerer. Use the reply link to reply to a particular user because that's the only way he will be notified. :thumbsup:
Here's an article showing how to do what you are asking: 'Extending' the Enum Class to Validate the Enum Values with the Flags Attribute[^]. Unfortunately, this is not an easy fix.

Another slightly hacky alternative would be to take the result of .ToString() from your enum and call Int32.TryParse. If the result is true, that means the value is returning as an integer string, not a named enum or combination of enums.

int myThrowAwayInt;
MyEnum MyEnumValue = (MyEnum)2|8;
bool notDefined = Int32.TryParse(MyEnumValue.ToString(), out myThrowAwayInt);
    //This enum value is not defined
#realJSOP 10-May-11 14:33pm
Check out my version. :)
Sergey Alexandrovich Kryukov 10-May-11 20:16pm
Nah! Please see correct solution.
Rick Shaub 10-May-11 23:09pm
See my comment. Also note that I did not down vote.
Given the following enum I think what your looking for is DaysEnumNeedsFlags.Saturday.HasFlag(DaysEnumNeedsFlags.Saturday)

public enum DaysEnumNeedsFlags
    None = 0,
    Monday = 1,
    Tuesday = 2,
    Wednesday = 4,
    Thursday = 8,
    Friday = 16,
    Saturday = 32,
    Sunday = 64,
    WeekDays = Monday | Tuesday | Wednesday | Thursday | Friday,
    Weekend = Saturday | Sunday
Heres an enum in C++/CLI that I am using to determine if columns on a grid have changed

[Flags] enum class m_FlagBits
        EXPIRY_ID = 1,
        DESCRIPTION = 2,
        EXPIRY_TYPE = 4,
        UNIT_ID = 8,
        FIXED_INTERVAL_ID = 16,
        DAY = 32,
        VALID_FROM = 128,
        VALID_TO = 256
m_FlagBits m_ElementList;

Make sure none of the values are set when I enter a row:
m_ElementList = m_ElementList & ~ m_FlagBits::EXPIRY_ID;
m_ElementList = m_ElementList & ~ m_FlagBits::EXPIRY_TYPE;
m_ElementList = m_ElementList & ~ m_FlagBits::DESCRIPTION;
m_ElementList = m_ElementList & ~ m_FlagBits::UNIT_ID;
m_ElementList = m_ElementList & ~ m_FlagBits::DAY;
m_ElementList = m_ElementList & ~ m_FlagBits::NUMBER_OF_INTERVAL_UNITS;
m_ElementList = m_ElementList & ~ m_FlagBits::FIXED_INTERVAL_ID;
m_ElementList = m_ElementList & ~ m_FlagBits::VALID_FROM;
m_ElementList = m_ElementList & ~ m_FlagBits::VALID_TO;

Setting one of them after changing a value:
m_ElementList = m_ElementList | m_FlagBits::EXPIRY_ID; 

Checking if one of them has been used
if (static_cast<int>(m_ElementList) & static_cast<int>(m_FlagBits::EXPIRY_ID))
   //Do Stuff like update the corresponding table
Once again, this is an answered question, but here's a hack-ish way to do this in very few lines of code. Full example below:

enum Nums
    One = 1,
    Two = 2,
    Four = 4

static void Main()
    Console.WriteLine(IsValidFlag<Nums>(3)); //true
    Console.WriteLine(IsValidFlag<Nums>(8)); //false

private static bool IsValidFlag<T>(int x) where T: struct
    return x.ToString() != ((T)(object)x).ToString();
You can check an or agains all numbers in decending order against your value and see if the result is zero.

static bool IsInNumbers(Type EnumType, int number) {
    var vals = Enum.GetValues(typeof(Numbers)).Cast<int>();
    for (int i = vals.Count() - 1; i >= 0; i--) {
        if ((vals.ElementAt(i) & number) == vals.ElementAt(i))
            number -= vals.ElementAt(i);
        return number==0;

comnplete example below

class Program {
    public enum Numbers {
        Zero = 0,
        One = 1,
        Two = 2,
        Three = 4,
        Four = 8
    static void Main(string[] args) {
        Type MyenumType = typeof(Numbers);
        Console.WriteLine(IsInNumbers(MyenumType, 1));
        Console.WriteLine(IsInNumbers(MyenumType, (int)(Numbers.Four | Numbers.Three)));
        Console.WriteLine(IsInNumbers(MyenumType, 9));
        Console.WriteLine(IsInNumbers(MyenumType, 23));

    static bool IsInNumbers(Type EnumType, int number) {
        var vals = Enum.GetValues(typeof(Numbers)).Cast<int>();
        for (int i = vals.Count() - 1; i >= 0; i--) {
            if ((vals.ElementAt(i) & number) == vals.ElementAt(i))
                number -= vals.ElementAt(i);
            return number==0;
cechode 10-May-11 12:55pm
ouch a 1 vote ( heh )

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900