如何在 C# 中比较标志?
我下面有一个标志枚举。
[Flags]
public enum FlagTest
{
None = 0x0,
Flag1 = 0x1,
Flag2 = 0x2,
Flag3 = 0x4
}
我无法使 if 语句评估为 true。
FlagTest testItem = FlagTest.Flag1 | FlagTest.Flag2;
if (testItem == FlagTest.Flag1)
{
// Do something,
// however This is never true.
}
我怎样才能实现这一点?
I have a flag enum below.
[Flags]
public enum FlagTest
{
None = 0x0,
Flag1 = 0x1,
Flag2 = 0x2,
Flag3 = 0x4
}
I cannot make the if statement evaluate to true.
FlagTest testItem = FlagTest.Flag1 | FlagTest.Flag2;
if (testItem == FlagTest.Flag1)
{
// Do something,
// however This is never true.
}
How can I make this true?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
对于位运算,需要使用按位运算符。
这应该可以解决问题:
编辑:修复了我的 if 检查 - 我又回到了我的 C/C++ 方式(感谢 Ryan Farley 指出)
For bit operations, you need to use bitwise operators.
This should do the trick:
Edit: Fixed my if check - I slipped back into my C/C++ ways (thanks to Ryan Farley for pointing it out)
还有一条建议...永远不要使用值为“0”的标志进行标准二进制检查。 您对此标志的检查将始终为真。
如果您根据 FullInfo 对输入参数进行二进制检查 - 您会得到:
bPRez 将始终为 true,因为 ANYTHING & 0 总是 == 0。
相反,您应该简单地检查输入的值是否为 0:
One more piece of advice... Never do the standard binary check with the flag whose value is "0". Your check on this flag will always be true.
If you binary check input parameter against FullInfo - you get:
bPRez will always be true as ANYTHING & 0 always == 0.
Instead you should simply check that the value of the input is 0:
(testItem & FlagTest.Flag1)
是按位 AND 运算。FlagTest.Flag1
相当于带有 OP 枚举的001
。 现在假设testItem
有 Flag1 和 Flag2(所以它是按位101
):(testItem & FlagTest.Flag1)
is a bitwise AND operation.FlagTest.Flag1
is equivalent to001
with OP's enum. Now let's saytestItem
has Flag1 and Flag2 (so it's bitwise101
):对于那些无法想象所接受的解决方案发生了什么的人
(就是这个),
testItem
(根据问题)定义为,然后,在 if 语句中,比较的左侧是,
以及完整的 if 语句(计算结果为 true如果在
testItem
中设置了flag1
),For those who have trouble visualizing what is happening with the accepted solution
(which is this),
testItem
(as per the question) is defined as,Then, in the if statement, the left hand side of the comparison is,
And the full if statement (that evaluates to true if
flag1
is set intestItem
),@phil-devaney
请注意,除了最简单的情况外,
超过 1000 万次迭代,HasFlags 扩展方法花费了高达 4793 毫秒的时间,而标准按位实现只需要 27 毫秒。
@phil-devaney
Note that except in the simplest of cases, the Enum.HasFlag carries a heavy performance penalty in comparison to writing out the code manually. Consider the following code:
Over 10 million iterations, the HasFlags extension method takes a whopping 4793 ms, compared to the 27 ms for the standard bitwise implementation.
我设置了一个扩展方法来执行此操作: 相关问题。
基本上:
然后你可以这样做:
顺便说一句,我用于枚举的约定对于标准是单数,对于标志是复数。 这样您就可以从枚举名称知道它是否可以容纳多个值。
I set up an extension method to do it: related question.
Basically:
Then you can do:
Incidentally the convention I use for enums is singular for standard, plural for flags. That way you know from the enum name whether it can hold multiple values.
尝试这个:
Basically, your code is asking if having both flags set is the same as having one flag set, which is obviously false. The code above will leave only the Flag1 bit set if it is set at all, then compares this result to Flag1.
Try this:
Basically, your code is asking if having both flags set is the same as having one flag set, which is obviously false. The code above will leave only the Flag1 bit set if it is set at all, then compares this result to Flag1.
即使没有 [Flags],您也可以使用类似的东西
,或者如果您有一个零值枚举
even without [Flags], you could use something like this
or if you have a Zero value enum
关于编辑。 你无法让它成为现实。 我建议您将所需的内容包装到另一个类(或扩展方法)中,以更接近您需要的语法。
IE
Regarding the edit. You can't make it true. I suggest you wrap what you want into another class (or extension method) to get closer to the syntax you need.
i.e.
在.NET 4中有一个新方法 枚举.HasFlag。 这允许你写:
在我看来,这更具可读性。
.NET 源表明这执行与接受的答案相同的逻辑:
In .NET 4 there is a new method Enum.HasFlag. This allows you to write:
which is much more readable, IMO.
The .NET source indicates that this performs the same logic as the accepted answer: