获取枚举标志的所有位的最佳方法?

发布于 2024-09-13 13:40:11 字数 173 浏览 2 评论 0原文

我有一个带有 Flags 属性的枚举。

我的问题是,我想获得所有选项的整数位掩码,而无需自己手动组合所有位。 我想这样做是为了与其他一些 int 字段进行比较,并且我想保护以防未来的开发人员向枚举添加更多位选项。

另一件事是我的枚举标志中的位将全部手动分配,所以我不能简单地获取下一个值并减去 1。

I have an enum with a Flags attribute.

My question is, I'd like to get an integer bitmask of all of the options without manually combining all the bits myself.
I want to do this to compare to some other int field, and I want to protect in case a future developer ads more bit options to the enum.

Another thing is the bits in my enum flags will be all manually assigned, so I cannot simply get the next value and subtract 1.

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

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

发布评论

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

评论(5

情未る 2024-09-20 13:40:11

如果我正确理解了您的要求,这应该对您有用:

Enum.GetValues(typeof(Enum)).Cast<int>().Sum();

然后您可以将其转换回您的 typeof(Enum)

[Flags]
public enum Values
{
    Value_1 = 1,
    Value_2 = 2,
    Value_3 = 4,
    Value_4 = 8,
    Value_5 = 16,
    Value_6 = 32,
    Value_7 = 64,
    Value_8 = 128,
    Value_9 = 256
}

static void Main(string[] args)
{
    Values values = (Values)Enum.GetValues(typeof(Values)).Cast<int>().Sum();
}

在此处输入图像描述

If I understood what you asked correctly this should work for you:

Enum.GetValues(typeof(Enum)).Cast<int>().Sum();

You can then cast it back to your typeof(Enum):

[Flags]
public enum Values
{
    Value_1 = 1,
    Value_2 = 2,
    Value_3 = 4,
    Value_4 = 8,
    Value_5 = 16,
    Value_6 = 32,
    Value_7 = 64,
    Value_8 = 128,
    Value_9 = 256
}

static void Main(string[] args)
{
    Values values = (Values)Enum.GetValues(typeof(Values)).Cast<int>().Sum();
}

enter image description here

你列表最软的妹 2024-09-20 13:40:11
// uses a ulong to handle all possible underlying types without error
var allFlags = Enum.GetValues(typeof(YourEnumType))
                   .Cast<YourEnumType>()
                   .Aggregate((YourEnumType)0, (a, x) => a | x, a => (ulong)a);
// uses a ulong to handle all possible underlying types without error
var allFlags = Enum.GetValues(typeof(YourEnumType))
                   .Cast<YourEnumType>()
                   .Aggregate((YourEnumType)0, (a, x) => a | x, a => (ulong)a);
眼泪也成诗 2024-09-20 13:40:11

看看我的 Unconstrained Melody 项目,它做了一些邪恶的事情来允许构建好的功能仅限于枚举和委托的通用方法。

在这种情况下,我认为您需要调用 Flags.GetUsedBits()

如果您不介意使用额外的(非常小的)库,我想 Unconstrained Melody 会让处理标志时的生活变得更加美好。如果您有任何功能请求,我很乐意查看:)

Have a look at my Unconstrained Melody project, which does evil things to allow nice features to be built on generic methods constrained to enums and delegates.

In this case, I think you'd want to call Flags.GetUsedBits<YourEnumType>().

If you don't mind using an extra (very small) library, I'd like to think that Unconstrained Melody makes life nicer when dealing with flags. If you have any feature requests, I'd be happy to have a look :)

夢归不見 2024-09-20 13:40:11

有点粗糙,但类似这样的东西?

[Flags]
enum SomeFlags
{
    Flag1 = 1,
    Flag2 = 2,
    Flag3 = 4,
    Flag4 = 16,
    Flag5 = 32,
    Flag6 = 64
}

static void Main(string[] args)
{
    SomeFlags flags = 0;

    SomeFlags[] values = (SomeFlags[])Enum.GetValues(typeof(SomeFlags));
    Array.ForEach<SomeFlags>(values, delegate(SomeFlags v) { flags |= v; });

    int bitMask = Convert.ToInt32(flags);
}

Kind of crude but something like this?

[Flags]
enum SomeFlags
{
    Flag1 = 1,
    Flag2 = 2,
    Flag3 = 4,
    Flag4 = 16,
    Flag5 = 32,
    Flag6 = 64
}

static void Main(string[] args)
{
    SomeFlags flags = 0;

    SomeFlags[] values = (SomeFlags[])Enum.GetValues(typeof(SomeFlags));
    Array.ForEach<SomeFlags>(values, delegate(SomeFlags v) { flags |= v; });

    int bitMask = Convert.ToInt32(flags);
}
給妳壹絲溫柔 2024-09-20 13:40:11

这是一种方法,使用 Jon 编写的 通用运算符 中的想法Skeet 和 Marc Gravell:

void Main()
{
    Console.WriteLine(CombineAllFlags<MyEnum>()); // Prints "Foo, Bar, Baz"
}

[Flags]
public enum MyEnum
{
    Foo = 1,
    Bar = 2,
    Baz = 4
}

public static TEnum CombineAllFlags<TEnum>()
{
    TEnum[] values = (TEnum[])Enum.GetValues(typeof(TEnum));
    TEnum tmp = default(TEnum);
    foreach (TEnum v in values)
    {
        tmp = EnumHelper<TEnum>.Or(tmp, v);
    }
    return tmp;
}

static class EnumHelper<T>
{
    private static Func<T, T, T> _orOperator = MakeOrOperator();

    private static Func<T, T, T> MakeOrOperator()
    {
        Type underlyingType = Enum.GetUnderlyingType(typeof(T));
        ParameterExpression xParam = Expression.Parameter(typeof(T), "x");
        ParameterExpression yParam = Expression.Parameter(typeof(T), "y");
        var expr =
            Expression.Lambda<Func<T, T, T>>(
                Expression.Convert(
                    Expression.Or(
                        Expression.Convert(xParam, underlyingType),
                        Expression.Convert(yParam, underlyingType)),
                    typeof(T)),
                xParam,
                yParam);
        return expr.Compile();
    }

    public static T Or(T x, T y)
    {
        return _orOperator(x, y);
    }   
}

此代码动态创建一个委托,将枚举值与 OR 运算符组合起来

Here's a way to do it, using ideas from the generic operators written by Jon Skeet and Marc Gravell :

void Main()
{
    Console.WriteLine(CombineAllFlags<MyEnum>()); // Prints "Foo, Bar, Baz"
}

[Flags]
public enum MyEnum
{
    Foo = 1,
    Bar = 2,
    Baz = 4
}

public static TEnum CombineAllFlags<TEnum>()
{
    TEnum[] values = (TEnum[])Enum.GetValues(typeof(TEnum));
    TEnum tmp = default(TEnum);
    foreach (TEnum v in values)
    {
        tmp = EnumHelper<TEnum>.Or(tmp, v);
    }
    return tmp;
}

static class EnumHelper<T>
{
    private static Func<T, T, T> _orOperator = MakeOrOperator();

    private static Func<T, T, T> MakeOrOperator()
    {
        Type underlyingType = Enum.GetUnderlyingType(typeof(T));
        ParameterExpression xParam = Expression.Parameter(typeof(T), "x");
        ParameterExpression yParam = Expression.Parameter(typeof(T), "y");
        var expr =
            Expression.Lambda<Func<T, T, T>>(
                Expression.Convert(
                    Expression.Or(
                        Expression.Convert(xParam, underlyingType),
                        Expression.Convert(yParam, underlyingType)),
                    typeof(T)),
                xParam,
                yParam);
        return expr.Compile();
    }

    public static T Or(T x, T y)
    {
        return _orOperator(x, y);
    }   
}

This code dynamically creates a delegate that combines enum values with the OR operator

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