如何检查是否设置了标志组合的任何标志?
假设我有这个枚举:
[Flags]
enum Letters
{
A = 1,
B = 2,
C = 4,
AB = A | B,
All = A | B | C,
}
要检查例如 AB
是否已设置,我可以这样做:
if((letter & Letters.AB) == Letters.AB)
是否有比以下更简单的方法来检查组合标志常量的任何标志是否已设置?
if((letter & Letters.A) == Letters.A || (letter & Letters.B) == Letters.B)
例如,可以用某些东西交换 &
吗?
Let's say I have this enum:
[Flags]
enum Letters
{
A = 1,
B = 2,
C = 4,
AB = A | B,
All = A | B | C,
}
To check if for example AB
is set I can do this:
if((letter & Letters.AB) == Letters.AB)
Is there a simpler way to check if any of the flags of a combined flag constant are set than the following?
if((letter & Letters.A) == Letters.A || (letter & Letters.B) == Letters.B)
Could one for example swap the &
with something?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(18)
在 .NET 4 中,您可以使用 Enum.HasFlag 方法 :
示例显示以下输出:
In .NET 4 you can use the Enum.HasFlag method :
The example displays the following output:
如果您想知道字母是否包含 AB 中的任何字母,则必须使用 AND
&
运算符。像这样的东西:If you want to know if letter has any of the letters in AB you must use the AND
&
operator. Something like:我使用扩展方法来编写类似的东西:
这是代码:
I use extension methods to write things like that :
Here's the code :
.NET 4 或更高版本中有 HasFlag 方法。
检查字母是否包含 A OR B
检查字母是否包含 A AND B
There is the HasFlag method in .NET 4 or higher.
Check if the letter includes A OR B
Check if the letter includes A AND B
如果您可以使用 .NET 4 或更高版本,则使用 HasFlag() 方法
示例
与
If you can use .NET 4 or higher than use HasFlag() method
examples
same as
如果它真的让你烦恼,你可以编写这样的函数:
If it really annoys you, you can write a function like that:
这会检查 A 和 B 是否均已设置,并忽略是否设置了任何其他标志。
这会检查 A 或 B 是否已设置,并忽略是否设置了任何其他标志。
这可以简化为:
这是用于二元运算的 C;将其应用到 C# 应该很简单:
顺便说一句,问题示例中变量的命名是单数“字母”,这可能意味着它仅代表单个字母;示例代码清楚地表明它是一组可能的字母并且允许多个值,因此请考虑重命名变量“字母”。
This checks that both A and B are set, and ignores whether any other flags are set.
This checks that either A or B is set, and ignores whether any other flags are set or not.
This can be simplified to:
Here's the C for binary operations; it should be straightforward to apply this to C#:
Incidentally, the naming of the variable in the question's example is the singular 'letter', which might imply that it represents only a single letter; the example code makes it clear that its a set of possible letters and that multiple values are allowed, so consider renaming the variable 'letters'.
怎么样
?
How about
?
我创建了一个简单的扩展方法,不需要检查
Enum
类型:它也适用于可为 null 的枚举。标准的 HasFlag 方法没有,所以我也创建了一个扩展来覆盖它。
一个简单的测试:
享受吧!
I created a simple extension method that does not need a check on
Enum
types:It also works on nullable enums. The standard
HasFlag
method does not, so I created an extension to cover that too.A simple test:
Enjoy!
对于任何类型的枚举,您可以在枚举上使用此扩展方法:
You can use this extension method on enum, for any type of enums:
这里有很多答案,但我认为使用标志执行此操作的最惯用方法是 Letters.AB.HasFlag(letter) 或 (Letters.A | Letters.B).HasFlag(letter) 如果您没有已经有了 Letters.AB。 letter.HasFlag(Letters.AB) 仅在同时具有两者时才有效。
There are a lot of answers on here but I think the most idiomatic way to do this with Flags would be Letters.AB.HasFlag(letter) or (Letters.A | Letters.B).HasFlag(letter) if you didn't already have Letters.AB. letter.HasFlag(Letters.AB) only works if it has both.
从 .Net 4 开始,您可以使用速记版本而无需显式指定 &:
Starting with .Net 4, you can use a shorthand version without explicitly specifying &:
这对你有用吗?
Would this work for you?
您可以检查该值是否不为零。
但我认为引入一个值为零的新枚举值并与该枚举值进行比较是一个更好的解决方案(如果可能的话,因为您必须能够修改枚举)。
更新
误读了问题 - 修复了第一个建议并忽略第二个建议。
You could just check if the value is not zero.
But I would consider it a better solution to introduce a new enumeration value with value zero and compare agains this enumeration value (if possible because you must be able to modify the enumeration).
UPDATE
Missread the question - fixed the first suggestion and just ignore the second suggestion.
我认为有两种方法可以用于检查是否设置了任何位。
方法 A
只要您不介意检查所有位(包括未定义的位),此方法就有效!
方法 B
这只检查定义的位,只要 Letters.All 代表所有可能的位。
对于特定位(一组或多组),请使用方法 B 将 Letters.All 替换为您要检查的位(见下文)。
There are two aproaches that I can see that would work for checking for any bit being set.
Aproach A
This works as long as you don't mind checking for all bits, including non-defined ones too!
Aproach B
This only checks the defined bits, as long as Letters.All represents all of the possible bits.
For specific bits (one or more set), use Aproach B replacing Letters.All with the bits that you want to check for (see below).
我们能否轻松高效地查明是否至少设置了一个标志?
好吧,如果您对检查是否至少设置了一个位感到满意,那么是的!
用法:
实现:
我们检查是否至少设置了一个标志位,这意味着什么?
好吧,这个解决方案可能无法正确回答如下所示的无意义枚举:
这里,
EnumHelper.HasAnyFlagBitSet((Nonsense)2)
将返回true
,即 技术上不正确,因为2
不是一个定义的标志。然而,它对于所有明智的标志枚举都非常有效,包括具有多标志的枚举:
Can we find out easily and efficiently whether at least one flag is set?
Well, if you are satisfied with checking whether at least one flag bit is set, then yes!
Usage:
Implementation:
What does it mean that we are checking if at least one flag bit is set?
Well, this solution may fail to answer correctly for nonsensical enums like the following:
Here,
EnumHelper.HasAnyFlagBitSet((Nonsense)2)
would returntrue
, which is technically incorrect, since2
is not a defined flag.However, it works perfectly fine for all sensible flags enums, including ones with multi-flags:
您可以直接对组合标志常量使用按位与运算符 (&),并检查结果是否不等于 0。
下面是一个使用 Letters 枚举中的 AB 标志的示例:
这是有效的,因为如果 Letters 中至少有一个标志,则按位 AND 运算只会产生非零结果。 AB 设置在 letter 变量中。如果结果为零,则表示 Letters 中没有任何标志。 AB 以字母形式设置。
您可以应用相同的方法来检查任何其他组合标志常量,例如 All:
通过以这种方式使用按位 AND 运算符,您可以简化检查并避免与标志常量本身进行显式比较。
You can use the bitwise AND operator (&) directly on the combined flag constant and check if the result is not equal to zero.
Here's an example using the AB flag from your Letters enum:
This works because the bitwise AND operation will only produce a non-zero result if at least one of the flags in Letters. AB is set in the letter variable. If the result is zero, it means none of the flags in Letters. AB are set in letter.
You can apply the same approach to check for any other combined flag constant, such as All:
By using the bitwise AND operator in this way, you can simplify the check and avoid explicitly comparing against the flag constant itself.