У меня есть флаг enum ниже.
[Flags]
public enum FlagTest
{
None = 0x0,
Flag1 = 0x1,
Flag2 = 0x2,
Flag3 = 0x4
}
Я не могу сделать утверждение if верным.
FlagTest testItem = FlagTest.Flag1 | FlagTest.Flag2;
if (testItem == FlagTest.Flag1)
{
// Do something,
// however This is never true.
}
Как я могу это сделать?
None
флаг со значением ноль. См msdn.microsoft.com/en-us/library/vstudio/...&
оператор для сравнения,|
это как дополнение:1|2=3
,5|2=7
,3&2=2
,7&2=2
,8&2=0
.0
оцениваетfalse
все остальноеtrue
.Ответы:
В .NET 4 появился новый метод Enum.HasFlag . Это позволяет вам написать:
что гораздо более читабельно, ИМО.
Источник .NET указывает, что он выполняет ту же логику, что и принятый ответ:
источник
Enum
класса.(testItem & FlagTest.Flag1)
это побитовая операция ИFlagTest.Flag1
эквивалентно001
с перечислением OP. Теперь, скажем,testItem
есть Flag1 и Flag2 (так что это поразрядно101
):источник
Для тех, у кого возникают проблемы с визуализацией того, что происходит с принятым решением (и это так),
testItem
(согласно вопросу) определяется как,Тогда в операторе if левая часть сравнения
И полный оператор if (который оценивается как true, если
flag1
установлен вtestItem
),источник
@ Фил-Devaney
Обратите внимание, что за исключением простейших случаев, Enum.HasFlag несет в себе значительное снижение производительности по сравнению с написанием кода вручную. Рассмотрим следующий код:
Более 10 миллионов итераций, метод расширения HasFlags занимает колоссальные 4793 мс, по сравнению с 27 мс для стандартной побитовой реализации.
источник
(«flag var» & «flag value») != 0
не работает для меня Условие всегда терпит неудачу, и мой компилятор (Unity3D Mono 2.6.5) выдает «предупреждение CS0162: Обнаружен недоступный код» при использовании вif (…)
.… = 1, … = 2, … = 4
на значениях перечисления критически важна при использовании[Flags]
. Я предполагал, что он будет1
автоматически начинать записи в Po2s и продвигаться по ним. Поведение выглядит одинаково для MS .NET и Uno от Mono. Приношу свои извинения вам.Я установил метод расширения, чтобы сделать это: связанный вопрос .
В принципе:
Тогда вы можете сделать:
Между прочим, соглашение, которое я использую для перечислений, единственное для стандартного, множественное для флагов. Таким образом, из имени перечисления вы узнаете, может ли оно содержать несколько значений.
источник
HasFlag
вместо этого использовать расширение.Еще один совет ... Никогда не делайте стандартную двоичную проверку с флагом, значение которого равно "0". Ваша проверка этого флага всегда будет верной.
Если вы проверяете двоичный входной параметр в FullInfo - вы получите:
bPRez всегда будет верным как НИЧЕГО, а 0 всегда == 0.
Вместо этого вы должны просто проверить, что значение ввода равно 0:
источник
источник
Для битовых операций вам нужно использовать побитовые операторы.
Это должно сделать трюк:
Редактировать: Исправлена проверка, если я - я вернулся к моим C / C ++ пути (спасибо Райан Фарли за указание на это)
источник
По поводу редактирования. Вы не можете сделать это правдой. Я предлагаю вам обернуть то, что вы хотите, в другой класс (или метод расширения), чтобы приблизиться к синтаксису, который вам нужен.
т.е.
источник
Попробуй это:
По сути, ваш код спрашивает, совпадают ли установленные оба флага с одним установленным флагом, что, очевидно, ложно. Приведенный выше код оставит установленным только бит Flag1, если он вообще установлен, затем сравнивает этот результат с Flag1.источник
даже без [Flags] вы можете использовать что-то вроде этого
или если у вас есть нулевое значение enum
источник