ElektroStudios ElektroStudios - 1 year ago 106
Vb.net Question

Best practice to determine the amount of flags contained in a Enum-flag combination?

In some scenearios, when I pass a Enum to a method, I need to handle whether it is a single Enum value, or otherwise it is a flag combination, for that purpose I wrote this simple extension:


Public Function FlagCount(ByVal sender As System.[Enum]) As Integer
Return sender.ToString().Split(","c).Count()
End Function

C# (online translation):

public int FlagCount(System.Enum sender) {
return sender.ToString().Split(',').Count();

Example Usage:


Dim flags As FileAttributes = (FileAttributes.Archive Or FileAttributes.Compressed)
Dim count As Integer = flags.FlagCount()

C# (online translation):

FileAttributes flags = (FileAttributes.Archive | FileAttributes.Compressed);
int count = flags.FlagCount();

I just would like to ask If exists a more direct and efficient way that what I'm currentlly doing to avoid represent the flag combination as a String then split it.

Answer Source

Option A:

public int FlagCount(System.Enum sender)
    bool hasFlagAttribute = sender.GetType().GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0;
    if (!hasFlagAttribute) // No flag attribute. This is a single value.
        return 1;

    var resultString = Convert.ToString(Convert.ToInt32(sender), 2);
    var count = resultString.Count(b=> b == '1');//each "1" represents an enum flag.
    return count;


  • If the enum does not have a "Flags attribute", then it is bound to be a single value.
  • If the enum has the "Flags attribute", Convert it to the bit representation and count the "1"s. each "1" represents an enum flag.

Option B:

  1. Get all flaged items.
  2. Count them...

The code:

public int FlagCount(this System.Enum sender)
  return sender.GetFlaggedValues().Count;

/// <summary>
/// All of the values of enumeration that are represented by specified value.
/// If it is not a flag, the value will be the only value returned
/// </summary>
/// <param name="value">The value.</param>
/// <returns></returns>
public static List<Enum> GetFlaggedValues(this Enum value)
    //checking if this string is a flagged Enum
    Type enumType = value.GetType();
    object[] attributes = enumType.GetCustomAttributes(true);

    bool hasFlags = enumType.GetCustomAttributes(true).Any(attr => attr is System.FlagsAttribute);
    //If it is a flag, add all flagged values
    List<Enum> values = new List<Enum>();
    if (hasFlags)
        Array allValues = Enum.GetValues(enumType);
        foreach (Enum currValue in allValues)
            if (value.HasFlag(currValue))
    else//if not just add current value
    return values;