说我有一个enum这样的定义:
[Flags]
public enum LogLevel
{
None = 1,
Pages = 2,
Methods = 4,
Exception =8
}
Run Code Online (Sandbox Code Playgroud)
和一个类似的类:
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
}
}
Run Code Online (Sandbox Code Playgroud)
我需要等于什么值Level来检查枚举是否包含Pages?
首先,标志必须具有一个None = 0值,因为否则就无法表示0掩码(即,没有value)。
修复它之后,您可以使用Enum.HasFlag或按位&运算符检查某些枚举值是否在给定的标志中:
Level.HasFlag(LogLevel.Pages);
Run Code Online (Sandbox Code Playgroud)
...要么:
(Level & LogLevel.Pages) == LogLevel.Pages
Run Code Online (Sandbox Code Playgroud)
最后,当实现标志枚举时,枚举标识符通常以复数形式表示。就您而言,您应该重构LogLevel为LogLevels。
&呢每个枚举值代表完整掩码中的一位。例如,None将为0,但也可以将其表示为0, 0, 0中每个0可能的枚举值之一LogLevels。当您提供类似的口罩时LogLevels.Pages | LogLevels.Methods,则口罩为1, 1, 0。
为了检查Pages掩码中是否包含掩码,可以使用逻辑与将掩码与可能的枚举值之一进行比较:
1, 1, 0 (LogLevels.Pages | LogLevels.Methods)
1, 0, 0 AND (LogLevels.Pages)
--------
1, 0, 0
Run Code Online (Sandbox Code Playgroud)
整个AND就像隔离测试的枚举值。如果生成的掩码等于枚举值,则该掩码包含枚举值。
OP在一些评论中说:
只是一个零值问题。此处表明您不能在按位AND操作中使用None枚举常量来测试标志,因为结果始终为零。这是否意味着如果我的值为0,则我不能使用&并且必须使用HasFlag?
None(即0)不会成为掩码的成员,因为0 不存在。生成遮罩时,您使用的是OR |逻辑运算符,最终,它是加法运算符。
想一想1 + 0 == 1。您是否认为有可能0在内部1?
实际上,该None = 0值需要能够表示并清空掩码。
最后,HasFlag这AND对您来说不是一个神奇的解决方案,而是一种更具可读性和封装性的执行所谓的的方式AND。