枚举的FlagsAttribute

时间:2013-02-22 05:19:55

标签: c# enums enumeration

我正在尝试用C#学习enum。当我在一些文件中读到时,我写了一个程序。但我没有 了解这个程序是如何工作的。有人可以帮我解决它的工作吗?

我在下面发布我的代码:

计划1:

public partial class MainPage {
    [Flags]
    enum Days {
        Monday,
        Tuesday,
        Wednesday,
        Thursday,
        Friday ,
        Saturday,
        Sunday
    };

    // Constructor
  public MainPage() {
        InitializeComponent();
        Days holidays = Days.Sunday | Days.Saturday;
        if ((Days.Sunday | holidays) == Days.Sunday) // This returns true. Why ?
            MessageBox.Show("True");
        else
            MessageBox.Show("False");
  }

计划2:

这里我在枚举

中指定整数值
public partial class MainPage {
    [Flags]
    enum Days {
        Monday = 1,
        Tuesday = 2,
        Wednesday = 5,
        Thursday = 8,
        Friday = 10,
        Saturday = 3,
        Sunday = 0
    };

    // Constructor
    public MainPage() {
        InitializeComponent();
        Days holidays = Days.Sunday | Days.Saturday;
        if ((Days.Sunday | holidays) == Days.Sunday) // Why this returns false ?
            MessageBox.Show("True");
        else
            MessageBox.Show("False");
  }

在程序2中分配整数值后,if条件有什么不同?

3 个答案:

答案 0 :(得分:3)

默认情况下,

枚举从0开始,例如:

[Flags]
enum Days
{
    Monday = 0,
    Tuesday = 1,
    Wednesday = 2,
    Thursday = 3,
    Friday = 4,
    Saturday = 5,
    Sunday = 6
};

我认为你对枚举中的按位运算符感到困惑。通常,为了使枚举与按位运算符一起使用,您可以像这样声明它们:

[Flags]
enum Days
{
    Monday = 0,
    Tuesday = 1,
    Wednesday = 2,
    Thursday = 4,
    Friday = 8,
    Saturday = 16,
    Sunday = 32
};

答案 1 :(得分:2)

看起来您将位操作符|与逻辑运算符||混淆。

在原始程序中,星期六分配为5,星期日分配为6。

按位OR:

8 4 2 1 
0 1 0 1 = 5 Saturday
0 1 1 0 = 6 Sunday
-----------
0 1 1 1 = 7 Result (Holiday).

按位OR:

8 4 2 1 
0 1 1 1 = 7 Holidays
0 1 1 0 = 6 Sunday
-----------
0 1 1 1 = 7 Result.

但是我运行了类似的代码:

using System;

namespace ConsoleApplication1
{
  class Program
  {
    [Flags]
    enum Days
    {
        Monday,     //Default 0
        Tuesday,    //Default 1
        Wednesday,  //Default 3
        Thursday,   //Default 4
        Friday,     //Default 5
        Saturday,   //Default 6
        Sunday      //Default 7
    };

    static void Main(string[] args)
    {
        Days holidays = Days.Sunday | Days.Saturday;
        if ((Days.Sunday | holidays) == Days.Sunday) // This returns true. Why ?
            Console.WriteLine("True");
        else
            Console.WriteLine("False");

        Console.ReadKey();
    }
  }
}

结果:False(在您的示例中不正确)。

正如预期的那样,7不等于6. 我的假设是您的示例中缺少代码或错误输入的代码。

如果您正确使用FlagsAttribute,我强烈建议您阅读{{3}}如何工作,这涉及在位值(1,2,4,8,16,32)处创建枚举。

如果您的代码已得到纠正,那么这可能更符合我认为您正在寻找的内容。

using System;

namespace ConsoleApplication1
{
  class Program
  {
    [Flags]
    enum Days
    {
        Monday    = 1,
        Tuesday   = 2,   
        Wednesday = 4, 
        Thursday  = 8, 
        Friday    = 16,   
        Saturday  = 32, 
        Sunday    = 64
    };

    static void Main(string[] args)
    {
        Days holidays = Days.Sunday | Days.Saturday;

        if ((Days.Sunday | holidays) == holidays)
            Console.WriteLine("Sunday is a Holiday");
        else
            Console.WriteLine("Sunday is a Holiday");

        if ((Days.Tuesday | holidays) == holidays)
            Console.WriteLine("Tuesday is not a Holiday");
        else
            Console.WriteLine("Tuesday is not a Holiday");

        Console.ReadKey();
    }
  }
}

结果:Sunday is a Holiday Tuesday is not a Holiday

这是因为,

按位OR:

64 32 16  8  4  2  1 
 0  1  0  0  0  0  0 = 32 Saturday
 1  0  0  0  0  0  0 = 64 Sunday
----------------------
 1  1  0  0  0  0  0 = 96 Result (Holiday).

按位OR:

64 32 16  8  4  2  1 
 1  1  0  0  0  0  0 = 96 Holiday
 1  0  0  0  0  0  0 = 64 Sunday
----------------------
 1  1  0  0  0  0  0 = 96 Result (Holiday).

按位OR:

64 32 16  8  4  2  1 
 1  1  0  0  0  0  0 = 96 Holiday
 0  0  0  0  0  1  0 = 32 Tuesday
----------------------
 1  1  0  0  0  1  0 = 97 Result (Not Holiday).

答案 2 :(得分:2)

为了补充Jeremy的答案,考虑他对Days的第二个(和正确的)定义 二进制表示是:

0000 0001   Monday
0000 0010   Tuesday
0000 0100   Wednesday
0000 1000   Thursday
0001 0000   Saturday
0010 0000   Sunday

接下来执行以下操作

var holidays = Days.Sunday | Days.Saturday;

执行按位或:

      0001 0000   Saturday
OR    0010 0000   Sunday
      --------------------
      0011 0000   Saturday | Sunday

接下来,请查看以下内容

((Days.Sunday | holidays) == Days.Sunday)

这意味着:

   0010 0000   Sunday
OR 0011 0000   holidays  (= Saturday | Sunday)
   ---------
   0011 0000   This is still holidays and does not equal Sundays

如果要检查“假日”是否设置了星期日位,则应使用按位AND

<(>(Days.Sunday&amp; holidays)== Days.Sunday)

    0010 0000   Sunday
AND 0011 0000   holidays  (= Saturday | Sunday)
    ---------
    0010 0000   Sunday

另请注意,.NET Framework的更新版本具有 内置支持标志检查:

var holidays = Days.Sunday | Days.Saturday
holidays.HasFlag(Days.Sunday)  //Will return true
holidays.HasFlag(Days.Monday)  //Will return false

您对Days枚号的定义不应与[Flags]一起使用, 如果您将此帖子中的相同逻辑应用于定义中的值 你会得到一些非常奇怪的结果。