Как получить значение из свойства перечисления [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?

2 3

2 ответа:

Во-первых, флаги должны иметь значение 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 внутри маски, вы используете логическое и сравнение маски с одним из возможных значений перечисления:

1, 1, 0 (LogLevels.Pages | LogLevels.Methods)
1, 0, 0 AND (LogLevels.Pages)
--------
1, 0, 0 
  • 1 и 1 (правда и правда = = правда)
  • 1 и 0 (true и false = = false)
  • 0 и 0 (false и false = = false).

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

Некоторые ОП касаются

ОП сказал в некотором Комментарии:

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

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

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

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

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

Вот так

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