C#中是否有模式或方法来检查(int 1,2,4,8,...)选项是真还是假

Bas*_*mme 5 c# enums bitflags boolean-operations

我喜欢写枚举或整数来传递我的方法选项.C#中是否有模式或方法来检查(int 1,2,4,8,...)选项是真还是假.我认为应该可以通过二进制函数轻松实现.

class Program
{
    public enum Option
    {
        Option_A = 1,
        Option_B = 2,
        Option_C = 4,
        Option_D = 8,
    }

    static void Main(string[] args)
    {
        int activeOption = 5; // Means I activeted the Option_A and Option_C
        if (IsOption(activeOption, Option.Option_A)) { /*do work*/ }
        if (IsOption(activeOption, Option.Option_B)) { /*do work*/ }
        if (IsOption(activeOption, Option.Option_C)) { /*do work*/ }
        if (IsOption(activeOption, Option.Option_D)) { /*do work*/ }
    }

    private static bool IsOption(int activeOption, Option option)
    {
        /*Evaluate if IsOption is true or false*/
        throw new NotImplementedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑

我是否限制了我可以创建的选项数量?

R. *_*des 10

由于您的枚举包含标志(或者如果您愿意,是一个位域),您应该添加一个标志FlagsAttribute:

[Flags]
public enum Option
{
    Option_A = 1,
    Option_B = 2,
    Option_C = 4,
    Option_D = 8,
}
Run Code Online (Sandbox Code Playgroud)

然后,检查通常使用按位和运算符完成.还需要强制转换,因为您正在使用int变量.

if(((Option)activeOption & Option.Option_A) != Option.Option_A) //...
Run Code Online (Sandbox Code Playgroud)

如果你想把这种肮脏的东西封装起来,请查看Smudge202答案中链接的文章.如果您运行的是.NET 4,则甚至不需要这样做:检查sehe的答案.

但你应该尝试Option直接使用类型的变量,并将选项与按位或运算符组合:

Option activeOption = Option.Option_A | Option.Option_C;
Run Code Online (Sandbox Code Playgroud)

当然,使用此方案会限制您可以创建的选项数量.如果保持原样,则只能创建32个不同的选项,因为int(枚举的默认基础类型)只有32位.如果你使用a,long你可以有64种不同的选择:

[Flags]
public enum Option : long
{
    Option_A = 1,
    Option_B = 2,
    Option_C = 4,
    Option_D = 8,
    // blah blah
}
Run Code Online (Sandbox Code Playgroud)

但是,如果您需要任意数量的选项,则可能需要更改策略.你可以制作一个行为类似枚举的自定义类型,但你可能只需要一个常规的非标志枚举和一个HashSet<Option>.

public enum Option
{
    Option_A = 1, // notice the sequential values now
    Option_B = 2,
    Option_C = 3,
    Option_D = 4,
}

HashSet<Option> options = new HashSet<Option> { Option.Option_A, Option.Option_C };
if(options.Contains(Option.Option_A)) // ...
Run Code Online (Sandbox Code Playgroud)