我想知道以下枚举掩码是如何工作的
如果我有一个枚举结构
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
我想知道任何人都可以帮我弄清楚哪个块会被执行吗?
答案 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后缀表示二进制表示法。
枚举值:
传递值:
48d = 110000b
现在&
是按位AND运算符。这意味着如果c = a& b,当且仅当a和b中的第n位为1时,c中的第n位将为1。
所以:
如您所见,您的号码48d与16d和32d“匹配”。这就是为什么这种枚举通常被描述为“标志”枚举:你可以用一个整数表示几个“标志”的值。
对于您的代码,将验证第一个if
运算符,这意味着您将输入它并执行“执行某些操作”。你不会“做别的事”。
通常在C#中,我们使用[Flags] attribute作为标记枚举,这不允许实际为枚举成员写入小数值。像往常一样,MSDN中的示例是无用的,因此我将参考此SO question以获取有关如何使用它的更多详细信息(请注意,要知道值x是否设置了标记f,您可以执行{ {1}}或x & f == f
,但用法似乎通常是使用后者。)