5

我喜欢编写枚举或整数来将选项传递给我的方法。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();
    }
}

编辑

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

4

5 回答 5

10

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

[Flags]
public enum Option
{
    Option_A = 1,
    Option_B = 2,
    Option_C = 4,
    Option_D = 8,
}

然后,通常使用按位和运算符进行检查。还需要强制转换,因为您使用的是int变量。

if(((Option)activeOption & Option.Option_A) != Option.Option_A) //...

如果您想消除这种讨厌,请查看Smudge202 的答案中链接的文章。如果您正在运行 .NET 4,您甚至不需要这样做:检查sehe 的答案

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

Option activeOption = Option.Option_A | Option.Option_C;

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

[Flags]
public enum Option : long
{
    Option_A = 1,
    Option_B = 2,
    Option_C = 4,
    Option_D = 8,
    // blah blah
}

但是,如果您需要任意数量的选项,则可能是时候改变策略了。您可以创建一个行为类似于枚举的自定义类型,但使用常规的非标志枚举和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)) // ...
于 2011-05-20T09:23:49.857 回答
3

使用按位与检查 中的位option是否设置在activeOption. 您还需要使两个参数的类型相同,以便运算符可以工作(无论如何您正在检查位Option掩码中的位):

private static bool IsOption(Option activeOption, Option option)
{
    return (activeOption & option) == option;
}
于 2011-05-20T09:23:31.510 回答
2

除了提到的 FlagsAttribute 之外,在 C# 中还有Enum.HasFlag 方法

using System;

[Flags] public enum DinnerItems {
   None = 0,
   Entree = 1,
   Appetizer = 2,
   Side = 4,
   Dessert = 8,
   Beverage = 16, 
   BarBeverage = 32
}

public class Example
{
   public static void Main()
   {
      DinnerItems myOrder = DinnerItems.Appetizer | DinnerItems.Entree |
                            DinnerItems.Beverage | DinnerItems.Dessert;
      DinnerItems flagValue = DinnerItems.Entree | DinnerItems.Beverage;
      Console.WriteLine("{0} includes {1}: {2}", 
                        myOrder, flagValue, myOrder.HasFlag(flagValue));
   }
}
// The example displays the following output:
//    Entree, Appetizer, Dessert, Beverage includes Entree, Beverage: True
于 2011-05-20T09:48:39.423 回答
1

如果您使用的是 .NET 4.0,则可以使用HasFlag.

static void Main(string[] args)
{
    Option activeOption = (Option)5; // Means I activeted the Option_A and Option_C
    if (activeOption.HasFlag(Option.Option_A)) { /*do work*/ }
    if (activeOption.HasFlag(Option.Option_B)) { /*do work*/ }
    if (activeOption.HasFlag(Option.Option_C)) { /*do work*/ }
    if (activeOption.HasFlag(Option.Option_D)) { /*do work*/ }
}
于 2011-05-20T13:36:13.910 回答
1

看看使用标志属性的枚举。

http://www.codeproject.com/Articles/37921/Enums-Flags-and-Csharp-Oh-my-bad-pun.aspx

于 2011-05-20T09:26:30.433 回答