如何从 [Flag] 枚举 属性 中检索值?
How do I retrieve a value from a [Flag] enum property?
假设我有一个 enum
定义如下:
[Flags]
public enum LogLevel
{
None = 1,
Pages = 2,
Methods = 4,
Exception =8
}
和 class 喜欢:
public static class Log
{
public static LogLevel Level = LogLevel.Methods | LogLevel.Pages;
public static void EnterPage([CallerFilePath]string filePath = "")
{
if (Level == //What value here to check if Level includes Pages?)
{
//Log
}
}
我需要将 Level
等同于什么值来检查枚举是否包含 Pages
?
像这样
if (Level.HasFlag(LogLevel.Pages))
{
//todo
}
首先,标志必须有一个 None = 0
值,否则无法表示 0
掩码(即 无值 )。
修复后,您可以使用 Enum.HasFlag
或按位 &
运算符检查某些枚举值是否在某个给定标志中:
Level.HasFlag(LogLevel.Pages);
...或:
(Level & LogLevel.Pages) == LogLevel.Pages
最后,当你实现一个flags枚举时,枚举标识符通常用复数表示。在您的情况下,您应该将 LogLevel
重构为 LogLevels
.
为什么 &
?
每个枚举值代表一个完整掩码中的一个位。例如,None
将是 0,但它也可以表示为 0, 0, 0
,其中每个 0
是 LogLevels
中可能的枚举值之一。当您提供像 LogLevels.Pages | LogLevels.Methods
这样的掩码时,掩码就是 1, 1, 0
.
为了检查 Pages
是否在掩码内,您使用逻辑 AND 将掩码与可能的枚举值之一进行比较:
1, 1, 0 (LogLevels.Pages | LogLevels.Methods)
1, 0, 0 AND (LogLevels.Pages)
--------
1, 0, 0
- 1 和 1(真和真 == 真)
- 1 和 0(真假 == 假)
- 0 和 0(假和假 == 假)。
整个AND就像把被测试的枚举值孤立起来一样。如果生成的掩码等于枚举值,则掩码包含枚举值。
一些 OP 问题
OP 在一些评论中说:
Just a quick question on zero value. here it states that You cannot
use the None enumerated constant in a bitwise AND operation to test
for a flag because the result is always zero. Does that mean if I have
a 0 value I cannot use & and must use HasFlag?
None
(即 0
)不会成为掩码的成员,因为 0 不存在 。当您生成掩码时,您使用的是 OR |
逻辑运算符,归根结底,这是一个加法。
想想1 + 0 == 1
。你认为检查 0
是否在 1
内是可能的吗?
实际上,需要 None = 0
值才能表示和清空掩码。
最后,HasFlag
为你做了AND
,这不是一个神奇的解决方案,而是一种更具可读性和封装性的方式来执行所谓的AND
。
假设我有一个 enum
定义如下:
[Flags]
public enum LogLevel
{
None = 1,
Pages = 2,
Methods = 4,
Exception =8
}
和 class 喜欢:
public static class Log
{
public static LogLevel Level = LogLevel.Methods | LogLevel.Pages;
public static void EnterPage([CallerFilePath]string filePath = "")
{
if (Level == //What value here to check if Level includes Pages?)
{
//Log
}
}
我需要将 Level
等同于什么值来检查枚举是否包含 Pages
?
像这样
if (Level.HasFlag(LogLevel.Pages))
{
//todo
}
首先,标志必须有一个 None = 0
值,否则无法表示 0
掩码(即 无值 )。
修复后,您可以使用 Enum.HasFlag
或按位 &
运算符检查某些枚举值是否在某个给定标志中:
Level.HasFlag(LogLevel.Pages);
...或:
(Level & LogLevel.Pages) == LogLevel.Pages
最后,当你实现一个flags枚举时,枚举标识符通常用复数表示。在您的情况下,您应该将 LogLevel
重构为 LogLevels
.
为什么 &
?
每个枚举值代表一个完整掩码中的一个位。例如,None
将是 0,但它也可以表示为 0, 0, 0
,其中每个 0
是 LogLevels
中可能的枚举值之一。当您提供像 LogLevels.Pages | LogLevels.Methods
这样的掩码时,掩码就是 1, 1, 0
.
为了检查 Pages
是否在掩码内,您使用逻辑 AND 将掩码与可能的枚举值之一进行比较:
1, 1, 0 (LogLevels.Pages | LogLevels.Methods)
1, 0, 0 AND (LogLevels.Pages)
--------
1, 0, 0
- 1 和 1(真和真 == 真)
- 1 和 0(真假 == 假)
- 0 和 0(假和假 == 假)。
整个AND就像把被测试的枚举值孤立起来一样。如果生成的掩码等于枚举值,则掩码包含枚举值。
一些 OP 问题
OP 在一些评论中说:
Just a quick question on zero value. here it states that You cannot use the None enumerated constant in a bitwise AND operation to test for a flag because the result is always zero. Does that mean if I have a 0 value I cannot use & and must use HasFlag?
None
(即 0
)不会成为掩码的成员,因为 0 不存在 。当您生成掩码时,您使用的是 OR |
逻辑运算符,归根结底,这是一个加法。
想想1 + 0 == 1
。你认为检查 0
是否在 1
内是可能的吗?
实际上,需要 None = 0
值才能表示和清空掩码。
最后,HasFlag
为你做了AND
,这不是一个神奇的解决方案,而是一种更具可读性和封装性的方式来执行所谓的AND
。