Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List all bit names from a flag Enum

I'm trying to make a helper method for listing the names of all bits set in an Enum value (for logging purposes). I want have a method that would return the list of all the Enum values set in some variables. In my example

[Flag]
Enum HWResponse
{
   None = 0x0,
   Ready = 0x1,
   Working = 0x2,
   Error = 0x80,
}

I feed it 0x81, and it should provide me with a IEnumerable<HWResponse> containing {Ready, Error}.

As I didn't find a simpler way, I tried to write the code below, but I can't make it compile.

public static IEnumerable<T> MaskToList<T>(Enum mask) 
{
  if (typeof(T).IsSubclassOf(typeof(Enum)) == false)
    throw new ArgumentException();

  List<T> toreturn = new List<T>(100);

  foreach(T curValueBit in Enum.GetValues(typeof (T)).Cast<T>())
  {
    Enum bit = ((Enum) curValueBit);  // Here is the error

    if (mask.HasFlag(bit))
      toreturn.Add(curValueBit);
  }

  return toreturn;
}

On this version of the code, the compiler complains that it can't cast T to Enum.

What did I do wrong? Is there a better (simpler) way to do this? How could I make the cast?

Also, I tried to write the method as

public static IEnumerable<T> MaskToList<T>(Enum mask) where T:Enum

but Enum is of a special type that forbids the 'where' syntax (Using C# 4.0)

like image 794
PPC Avatar asked Apr 11 '12 18:04

PPC


1 Answers

Here's a simple way to write it using LINQ:

public static IEnumerable<T> MaskToList<T>(Enum mask)
{
    if (typeof(T).IsSubclassOf(typeof(Enum)) == false)
        throw new ArgumentException();

    return Enum.GetValues(typeof(T))
                         .Cast<Enum>()
                         .Where(m => mask.HasFlag(m))
                         .Cast<T>();
}
like image 110
Gabe Avatar answered Oct 21 '22 05:10

Gabe