制作枚举面具c#

时间:2012-11-01 11:07:38

标签: c# enums

我想知道以下枚举掩码是如何工作的

如果我有一个枚举结构

public enum DelMask
{
        pass = 1,       
        fail = 2,       
        abandoned = 4,        
        distinction = 8,             
        merit = 16,        
        defer = 32,        
}

我见过以下代码

int pass = 48;
if ((pass & (int)DelMask.defer) > 0)
   //Do something
else if ((pass & (int)DelMask.merit ) > 0)
   //Do something else

我想知道任何人都可以帮我弄清楚哪个块会被执行吗?

5 个答案:

答案 0 :(得分:3)

这里的基本位逻辑。整数48以二进制形式结束:

0011 0000

Defer,32岁,是:

0010 0000

Merit,16岁,是:

0001 0000

现在,当您执行逻辑AND(&)时,结果位将设置在输入中的位置:

pass & (int)DelMask.defer

0011 0000 
0010 0000
========= & 
0010 0000    

结果将是16,因此((pass & (int)DelMask.defer) > 0)将评估为true。在您的示例中,if都将评估为true,因为输入中都存在两个标志。但是第二个不会被评估,因为它是else if

答案 1 :(得分:1)

两者都是正确的,所以第一个会被执行。

16是10000

32是100000

48是16 + 32所以它是110000

10000& 110000是10000

100000& 110000是100000

两者都大于零。

答案 2 :(得分:1)

48 = 16(优点)+32(推迟)。

因此pass & (int)DelMask.defer的计算结果为32,所以第一个块运行。

如果不是这种情况,pass & (int)DelMask.merit的计算结果为16,那么第二个块就会运行得那么远。

这只能起作用,因为枚举中的值都是2的不同幂,因此对应于基础int中的独立位。这就是所谓的位标志枚举。

答案 3 :(得分:1)

首先,它应该是int pass = 48; 基本上,此代码检查是否在数字的二进制表示中设置了位。每个&操作应该产生一个全零的结果,一个在掩码中的位置。例如:

48:         110000
defer = 32: 100000
            ______
          & 100000

所以你可以使用这段代码:

int pass = 48;
if ((pass & (int)DelMask.defer) == (int)DelMask.defer)
   //Do something
else if ((pass & (int)DelMask.merit ) == (int)DelMask.merit)
   //Do something else

答案 4 :(得分:1)

你需要将这些数字视为二进制数。我将使用d后缀显示十进制表示法,使用b后缀表示二进制表示法。

枚举值:

  • 01d = 000001b
  • 02d = 000010b
  • 04d = 000100b
  • 08d = 001000b
  • 16d = 010000b
  • 32d = 100000b

传递值:

48d = 110000b

现在&是按位AND运算符。这意味着如果c = a& b,当且仅当a和b中的第n位为1时,c中的第n位将为1。

所以:

  • 16d& 48d = 010000b = 16d> 0
  • 32d& 48d = 100000b = 32d> 0

如您所见,您的号码48d与16d和32d“匹配”。这就是为什么这种枚举通常被描述为“标志”枚举:你可以用一个整数表示几个“标志”的值。

对于您的代码,将验证第一个if运算符,这意味着您将输入它并执行“执行某些操作”。你不会“做别的事”。

通常在C#中,我们使用[Flags] attribute作为标记枚举,这不允许实际为枚举成员写入小数值。像往常一样,MSDN中的示例是无用的,因此我将参考此SO question以获取有关如何使用它的更多详细信息(请注意,要知道值x是否设置了标记f,您可以执行{ {1}}或x & f == f,但用法似乎通常是使用后者。)