C# 将标志枚举类型变量中的设置标志转换为整数数组

发布于 2024-09-08 21:38:10 字数 1105 浏览 5 评论 0原文

我想出了这段代码,它将设置的标志转换为标志枚举类型的变量,并将设置的标志作为整数返回。 我想知道这是否是最好的方法。

枚举示例:

[Flags]
enum Status {
  None = 0x0,
  Active = 0x1,
  Inactive = 0x2,
  Canceled = 0x4,
  Suspended = 0x8
}

我想出的将设置标志转换为 int 数组的扩展方法:

public static class Extensions
{
    public static int[] ToIntArray(this System.Enum o) 
    {
        return o.ToString()
            .Split(new string[] { ", " }, StringSplitOptions.None)
            .Select(i => (int)Enum.Parse(o.GetType(), i))
            .ToArray();
    }
}

这就是我使用它的方式:

Status filterStatus = Status.Suspended | Status.Canceled;

int[] filterFlags = filterStatus.toIntArray();

foreach (int flag in filterFlags) {
   Console.WriteLine("{0}\n", flag);
}

它将输出:

4
8

如您所见,为了完成此操作,我正在执行以下操作:

  1. 将变量转换为字符串。它输出类似: Suspending, Canceled
  2. 将该字符串拆分为字符串数组: { "Suspending", "Canceled" }
  3. 使用 Enum.Parse 将该字符串转换为枚举值。
  4. 将值转换为整数。
  5. 将 IEnumerable 转换为 int[]。

它有效,但我认为这不是最好的方法。有什么建议可以改进这段代码吗?

I came up with this piece of code that converts the set flags in a variable of type Flag Enumeration and returns the set flags as integers.
I'd like to know if this is the best approach.

Example enumeration:

[Flags]
enum Status {
  None = 0x0,
  Active = 0x1,
  Inactive = 0x2,
  Canceled = 0x4,
  Suspended = 0x8
}

The extension method that converts the set flags to array of int that I came up with:

public static class Extensions
{
    public static int[] ToIntArray(this System.Enum o) 
    {
        return o.ToString()
            .Split(new string[] { ", " }, StringSplitOptions.None)
            .Select(i => (int)Enum.Parse(o.GetType(), i))
            .ToArray();
    }
}

This is how I use it:

Status filterStatus = Status.Suspended | Status.Canceled;

int[] filterFlags = filterStatus.toIntArray();

foreach (int flag in filterFlags) {
   Console.WriteLine("{0}\n", flag);
}

It will output:

4
8

As you can see, to get this done I'm doing the following:

  1. Converting the variable to string. It outputs something like: Suspended, Canceled
  2. Splitting that string into an array of strings: { "Suspended", "Canceled" }
  3. Converting that string to the enumeration value with Enum.Parse.
  4. Casting the value to an integer.
  5. Converting the IEnumerable to int[].

It works, but I just don't think it's the best approach. Any suggestions to improve this bit of code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

幸福丶如此 2024-09-15 21:38:10

保持类似于 linq

var flags = Enum.GetValues(typeof(Status))
                .Cast<int>()
                .Where(f=> f & o == f)
                .ToList();

这种方法的一个问题是它将包含聚合枚举值。例如:

[Flags]
public enum Status
{
    None = 0,
    One = 1,
    Two = 2,
    All = One | Two,
}

var flags = Enum.GetValues(typeof(Status))
                .Cast<int>()
                .Where(f=> f & o == f)
                .ToList();

这里 flags 将有 1, 2, 3,而不仅仅是 1, 2

To keep it linq-like

var flags = Enum.GetValues(typeof(Status))
                .Cast<int>()
                .Where(f=> f & o == f)
                .ToList();

One gotcha with this approach is that it will include aggregate enumeration values. For example:

[Flags]
public enum Status
{
    None = 0,
    One = 1,
    Two = 2,
    All = One | Two,
}

var flags = Enum.GetValues(typeof(Status))
                .Cast<int>()
                .Where(f=> f & o == f)
                .ToList();

Here flags will have 1, 2, 3, not just 1, 2.

笛声青案梦长安 2024-09-15 21:38:10

只需转换为 int,然后打印出各个位。

int x = (int)o
List<int> flags = new List<int>();
for(int i = 1; i < (1 << 30); i <<= 1)
    if(x & i != 0)
        flags.Add(i);
return flags;

Just cast to an int, and then print out individual bits.

int x = (int)o
List<int> flags = new List<int>();
for(int i = 1; i < (1 << 30); i <<= 1)
    if(x & i != 0)
        flags.Add(i);
return flags;
明媚殇 2024-09-15 21:38:10

那么,您可以将步骤 1-3 替换为调用 <代码>Enum.GetValues。然后使用按位 & 运算符来测试您的值中设置了哪些。这比使用字符串要快得多。

此方法将支持超过一位宽的标志。如果所有位都是独立的,则只需 按照 Anon 说的去做

Well, you can replace steps 1-3 with a call to Enum.GetValues. And then use the bitwise & operator to test which of those are set in your value. This will be much faster than working with strings.

This method will support flags which are more than a single bit wide. If all bits are independent, just do what Anon said.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文