如何从[Flag]枚举属性中检索值?

时间:2015-11-20 14:12:28

标签: c# enums flags

说我有sed定义如下:

int main(int argc, char *argv[])
{
    FILE * f;
    const size_t buffersize = 2048;
    size_t length, filesize, position;
    char buffer[buffersize + 1];

    if (argc < 2) {
        fprintf(stderr, "Please provide file to mongofix!\n");
        exit(EXIT_FAILURE);
    };

    f = fopen(argv[1], "r+");

    /* get the full filesize */
    fseek(f, 0, SEEK_END);
    filesize = ftell(f);

    /* Ignore the first character */
    fseek(f, 1, SEEK_SET);

    while (1) {
        /* read chunks of buffersize size */
        length = fread(buffer, 1, buffersize, f);
        position = ftell(f);

        /* write the same chunk, one character before */
        fseek(f, position - length - 1, SEEK_SET);
        fwrite(buffer, 1, length, f);

        /* return to the reading position */
        fseek(f, position, SEEK_SET);

        /* we have finished when not all the buffer is read */
        if (length != buffersize)
            break;
    }

    /* truncate the file, with two less characters */
    ftruncate(fileno(f), filesize - 2);

    fclose(f);

    return 0;
};

和类似:

enum

我需要将[Flags] public enum LogLevel { None = 1, Pages = 2, Methods = 4, Exception =8 } 等同于检查枚举是否包含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 } } 有什么价值?

2 个答案:

答案 0 :(得分:5)

首先,标记必须具有None = 0值,否则无法表示0掩码(即无值)。< / p>

修复后,您可以使用Enum.HasFlag或按位&运算符检查某个枚举值是否在某个给定标记中:

Level.HasFlag(LogLevel.Pages);

...或:

(Level & LogLevel.Pages) == LogLevel.Pages

最后,当您实现flags枚举时,通常枚举标识符以复数形式表示。在您的情况下,您应该将LogLevel重构为LogLevels

为什么&

每个枚举值表示完整掩码中的一个位。例如,None将为0,但也可以表示为0, 0, 0,其中每个0LogLevels中可能的枚举值之一。当您提供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(真实且真实== true)
  • 1和0(真和假==假)
  • 0和0(假和假==假)。

整个 AND 就像隔离测试的枚举值一样。如果结果掩码等于枚举值,则掩码包含枚举值。

一些OP关注

OP在一些评论中表示:

  

关于零价值的快速问题。 here它表明你做不到   在按位AND运算中使用None枚举常量进行测试   对于一个标志,因为结果总是为零。这是否意味着我有   一个0值,我不能使用&amp;并且必须使用HasFlag?

None(即0)不会成为面具的成员,因为0 不存在。当您生成掩码时,您正在使用 OR |逻辑运算符,即在一天结束时添加。

想想1 + 0 == 1。您是否认为检查0是否在1范围内?

实际上,None = 0值需要能够表示和清空掩码。

最后,HasFlag为您执行AND,它不是一个神奇的解决方案,而是一种更具可读性和封装性的方式来执行所谓的AND。< / p>

答案 1 :(得分:0)

像这样

if (Level.HasFlag(LogLevel.Pages))
{             
   //todo  
}