Question

Can someone please help me to understand the internal logic of HasFlag method for a enum class? Let me first explain my requirement. I have already created an enum with flag attribute, and then used HasFlag() function to get selected combination from a bit flag value. But here my requirement is different. I have a table in my DB, which is having different enumeration values listed. the structure is like below.

EnumTypeID    EnumVal      EnumID     Description 
===========  ==========   =========  ================
   1           enum1          0         xxxxxxxxx
   1           enum2          1         xxxxxxxxx
   1           enum3          2         xxxxxxxxx
   2           enum4          0         xxxxxxxxx
   2           enum5          1         xxxxxxxxx

Let's say I have another table, which is storing the final flag combination for EnumTypeID 1. So that table column is suppose to save different combination like

0 = Nothing selected
1 = enum1 selected
2 = enum2 selected
3 = enum1 & enum2 selected
4 = enum3 selected
5 = enum1 & enum3 selected
6 = enum2 & enum3 selected
7 = enum1 & enum2 & enum3 selected

=============================================================

Now how can I programmatically(in C# .net4.5) achieve this. I need to first query the first table and get the list of enumeration for a specific EnumTypeID. Now I need to get the value from the second table for the selected flag (let's say the value is 5). Then how I can say that basically enum1 & enum3 is selected through code?

Was it helpful?

Solution

as you can see in the below link the HasFlag returns the result of thisInstance And flag = flag expression

Enum.HasFlag

see remarks section

and if I got your question correctly you need a query like this:

select * from SecondTable where FlagColumn & 5 = 5

OTHER TIPS

If I had to implement the method Enum.HasFlag, I would write it like that.

public static bool HasFlag2(this Enum e, Enum flag)
{
    // Check whether the flag was given
    if (flag == null)
    {
        throw new ArgumentNullException("flag");
    }

    // Compare the types of both enumerations
    if (!e.GetType().IsEquivalentTo(flag.GetType()))
    {
        throw new ArgumentException(string.Format(
            "The type of the given flag is not of type {0}", e.GetType()),
            "flag");
    }

    // Get the type code of the enumeration
    var typeCode = e.GetTypeCode();

    // If the underlying type of the flag is signed
    if (typeCode == TypeCode.SByte || typeCode == TypeCode.Int16 || typeCode == TypeCode.Int32 || typeCode == TypeCode.Int64)
    {
        return (Convert.ToInt64(e) & Convert.ToInt64(flag)) != 0;
    }

    // If the underlying type of the flag is unsigned
    if (typeCode == TypeCode.Byte || typeCode == TypeCode.UInt16 || typeCode == TypeCode.UInt32 || typeCode == TypeCode.UInt64)
    {
        return (Convert.ToUInt64(e) & Convert.ToUInt64(flag)) != 0;
    }

    // Unsupported flag type
    throw new Exception(string.Format("The comparison of the type {0} is not implemented.", e.GetType().Name));
}

It performs a binary comparison with the AND operator. More info here. If needed, you can test its behavior in Visual Studio, it's an extension method.

Hope it helps.

EDIT 2014-01-10

The Enum type doesn't implement the & operator, making our work harder when trying to compare the flags manually. They must be casted in the underlying type of the enumeration (which implements the & operator).

I updated my code in order to handle all the possible types for an enumeration. Basically, we retrieve the underlying type of the enumeration and cast them depending whether they are signed or unsigned.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top