Как получить значение из свойства перечисления [Flag]?

Скажем, у меня есть 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
        }
    }

Какое значение мне нужно приравнять Level к, чтобы проверить, включает ли перечисление Pages?


person user1    schedule 20.11.2015    source источник
comment
См. stackoverflow.com/questions/8447/   -  person    schedule 20.11.2015


Ответы (2)


Прежде всего, флаги должны иметь значение None = 0, потому что в противном случае невозможно представить маску 0 (т. Е. без значения).

После того, как вы его исправили, вы можете проверить, находится ли какое-либо значение перечисления в каком-либо заданном флаге, используя _ 3_ или побитовый & оператор:

Level.HasFlag(LogLevel.Pages);

...or:

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

Наконец, когда вы реализуете перечисление флагов, обычно идентификатор перечисления выражается во множественном числе. В вашем случае вам следует выполнить рефакторинг 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 
  • 1 и 1 (истина и истина == истина)
  • 1 и 0 (истина и ложь == ложь)
  • 0 и 0 (ложь и ложь == ложь).

Все операции И похожи на изолирование проверенного значения перечисления. Если результирующая маска равна значению перечисления, то маска содержит значение перечисления.

Некоторая озабоченность OP

OP сказал в каком-то комментарии:

Просто быстрый вопрос о нулевом значении. здесь говорится, что вы не можете использовать перечисляемую константу None в побитовой операции И для проверки флага, потому что результат всегда нуль. Означает ли это, что если у меня есть значение 0, я не могу использовать & и должен использовать HasFlag?

None (т.е. 0) не будет членом маски, потому что 0 не существует. При создании маски вы используете логический оператор OR |, который, в конце концов, является дополнением.

Подумайте о 1 + 0 == 1. Вы думаете, что проверка, находится ли 0 в пределах 1, когда-либо возможна?

Фактически, значение None = 0 требуется, чтобы иметь возможность представлять и пустую маску.

Наконец, HasFlag делает AND за вас, это не волшебное решение, а более читаемый и инкапсулированный способ выполнения так называемого AND.

person Matías Fidemraizer    schedule 20.11.2015

нравится

if (Level.HasFlag(LogLevel.Pages))
{             
   //todo  
}
person chsword    schedule 20.11.2015