Как получить значение из свойства перечисления [Flag]? [дубликат]
На этот вопрос уже есть ответ здесь:
- Что означает атрибут [Flags] Enum в C#? 10 ответов
Скажем, что у меня есть 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 ответа:
Во-первых, флаги должны иметь значение
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
.