Флаги перечисляют странные значения

[Flags]
public enum Direction
{
    None = 0x0000,
    Left = 0x0001,
    Right = 0x0002,
    Up = 0x0004,
    Down = 0x0008,
    Forward = 0x0016,
    Backward = 0x0032
}

Действительно запутался, я использую это перечисление в выражении if, например:

if ((enumValues & Direction.Forward) == Direction.Forward)
{
    // do stuff
}

чтобы проверить, содержит ли он флаг внутри коллекции.

if ((enumValues & Direction.Right) == Direction.Forward)
{
    // do stuff
}

Продолжает выполнение этого if ( Direction.Right ) кода, несмотря на то, что он не содержит флага Right внутри коллекции, я даже отлаживал его с перерывами, и значение не содержит Direction.Right, но он все равно возвращает true и запускает фрагмент.

Я неправильно настроил свое перечисление или неправильно запрашиваю значения?

Обычно я не использую флаги, я просто подумал, что было бы неплохо их использовать.


person ClownFishUK    schedule 23.02.2019    source источник
comment
не могли бы вы показать, откуда взялся enumValues ?   -  person er-sho    schedule 23.02.2019
comment
Почему бы тебе не использовать более обычные флаги? Как Left = 1 и Up = 0?   -  person Bogdan Doicin    schedule 23.02.2019
comment
if ((enumValues & Direction.Right) == Direction.Forward) - у вас там два разных значения.   -  person Wai Ha Lee    schedule 23.02.2019


Ответы (2)


Увидев, как вы определили свое перечисление:

None = 0x0000,
Left = 0x0001,
Right = 0x0002,
Up = 0x0004,
Down = 0x0008,
Forward = 0x0016,
Backward = 0x0032

Вы путаете шестнадцатеричные и десятичные числа.

В перечислении [Flags] двоичное представление значений вашего перечисления должно быть примерно таким:

0000 0000 0000 0000 0000 0000 0000 0001
0000 0000 0000 0000 0000 0000 0000 0010
0000 0000 0000 0000 0000 0000 0000 0100
0000 0000 0000 0000 0000 0000 0000 1000

Которые в десятичном формате являются степенями 2: 1, 2, 4, 8, 16 и т. Д.

Но то, как вы пишете, значения начинаются с 0x, что означает шестнадцатеричное значение. Таким образом, вы фактически устанавливаете значения для случая перечисления как шестнадцатеричные числа 1, 2, 4, 8 и 16.

Вам следует удалить эти 0x:

None = 0,
Left = 1,
Right = 2,
Up = 4,
Down = 8,
Forward = 16,
Backward = 32
person Sweeper    schedule 23.02.2019
comment
Спасибо за ответ, все разобрал :) - person ClownFishUK; 23.02.2019
comment
@ClownFishUK Вы также можете написать Left = 1 << 0, Right = 1 << 1, Up = 1 << 2, Down = 1 << 3 и т. Д., Что избавит вас от хлопот, связанных с самостоятельными вычислениями и ошибками. Это работает, потому что ‹< - это оператор сдвига левого бита, который здесь перемещает 1 бит на указанное количество позиций влево. Написание 1 << 5, на мой взгляд, также проясняет, на какой бит ссылается значение вроде 32. - person ckuri; 23.02.2019

Для шестнадцатеричного числа вы должны определить такие значения:

Forward = 0x0010,
Backward = 0x0020

Или в десятичном виде:

Forward = 16,
Backward = 32
person shingo    schedule 23.02.2019