Home > Net >  C# Flag get values of combination flag
C# Flag get values of combination flag

Time:01-12

I have an enum with [Flags] attribute, e.g.

[Flags]
public enum PhoneService
{
   None = 0,
   LandLine = 1,
   Cell = 2,
   Fax = 4,
   Internet = 8,
   All = LandLine | Cell | Fax | Internet
}

// Should print "LandLine, Cell, Fax, Internet"
Console.WriteLine(PhoneService.All);

How to get all the underlying values in the combination flag All?

CodePudding user response:

In case you have names for bits within enum you can try something like this:

using System.Reflection;

...

public static string NameToBits<T>(T value) where T : Enum {
  // If not marked with `Flags` return name without splitting into bits
  if (typeof(T).GetCustomAttribute(typeof(FlagsAttribute)) == null)
    return Enum.GetName(typeof(T), value);

  IEnumerable<string> Names() {
    ulong data = Convert.ToUInt64(value);

    for (int i = 0; i < 64;   i)
      if ((data & (1ul << i)) != 0)
        yield return Enum.GetName(typeof(T), 1ul << i);
  }

  return string.Join(", ", Names());
}

Demo:

public enum PhoneService {
  None = 0,

  LandLine = 1,
  Cell = 2,
  Fax = 4,
  Internet = 8,

  // Let's have more combinations
  Offline = LandLine | Cell | Fax,

  All = LandLine | Cell | Fax | Internet
}

...

Console.Write(NameToBits(PhoneService.All));

Output:

LandLine, Cell, Fax, Internet

You can implement NameToBits as a extension method, e.g.

public static class EnumsExtensions {
  public static string NameToBits<T>(this T value) where T : Enum {
    // If not marked with `Flags` return name without splitting into bits
    if (typeof(T).GetCustomAttribute(typeof(FlagsAttribute)) == null)
      return Enum.GetName(typeof(T), value);

    IEnumerable<string> Names() {
      ulong data = Convert.ToUInt64(value);

      for (int i = 0; i < 64;   i)
        if ((data & (1ul << i)) != 0)
          yield return Enum.GetName(typeof(T), 1ul << i);
    }

    return string.Join(", ", Names());
  }
}

and then use it like this:

Console.Write(PhoneService.All.NameToBits());

Fiddle

CodePudding user response:

You can write a utility method to do that:

public List<PhoneService> GetSubFlags(PhoneService item)
{
    return Enum.GetValues<PhoneService>()
        .Where(ps => item.HasFlag(ps) && item != ps)
        .ToList();
}

and you can use it to print the values like this:

var subFlags = GetSubFlags(PhoneService.All);
Console.WriteLine(string.Join(", ", subFlags));
  • Related