.net C#标志获取组合标志的值

ltskdhd1  于 2023-01-18  发布在  .NET
关注(0)|答案(2)|浏览(121)

我有一个带有[Flags]属性的 enum,例如

[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);

如何获取组合标志All中的所有底层值?

sdnqo3pr

sdnqo3pr1#

如果您在enum中有 * bits * 的名称,您可以尝试如下操作:

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());
}

演示:

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));

输出:

LandLine, Cell, Fax, Internet

您可以将NameToBits实现为 * extension * 方法,例如:

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());
  }
}

然后像这样使用它:

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

Fiddle

voase2hg

voase2hg2#

您可以编写一个实用程序方法来完成此操作:

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

你可以用它来打印如下的值:

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

相关问题