Что означает условное выражение для проверки эквивалентности DrawItemState в Windows Forms? - PullRequest
0 голосов
/ 18 января 2019

Я читал документацию DrawItemState и обнаружил следующий фрагмент кода:

if ((e.State & DrawItemState.Selected) == DrawItemState.Selected )
          brush = SystemBrushes.HighlightText;

В документации дано следующее объяснение

Поскольку состояние может быть комбинацией (бит-флагом) значений перечисления, вы не можете используйте "==", чтобы сравнить их

Однако я до сих пор не понимаю, чем это условное выражение отличается от фрагмента, показанного ниже:

if (e.State == DrawItemState.Selected )
          brush = SystemBrushes.HighlightText;

Кроме того, я не понимаю, как побитовый оператор AND & имеет значение и почему он даже включен в условное выражение.

1 Ответ

0 голосов
/ 18 января 2019

Из-за базовых значений перечисления вы можете установить несколько значений ( битовая комбинация ):

var state = DrawItemState.Disabled | DrawItemState.Grayed;

Это означает, что оба вернутся false:

Console.WriteLine(state == DrawItemState.Disabled);  // false
Console.WriteLine(state == DrawItemState.Grayed);    // false

Один из способов проверить значения - использовать побитовые операторы "и":

Console.WriteLine((state & DrawItemState.Grayed) == DrawItemState.Grayed);  // true

По сути, state в моем примере имеет два установленных бита - для «Серого» и «Отключено». Используя побитовые операторы «и» со значением «Grayed», результатом также является значение «Grayed».

0 0 0 0 0 0 0 0 1 1 0    // binary value of disabled and grayed

0 0 0 0 0 0 0 0 0 1 0    // binary value of grayed

0 0 0 0 0 0 0 0 0 1 0    // result is same value as grayed

Вы также можете проверить несколько флагов:

Console.WriteLine((state & (DrawItemState.Grayed | DrawItemState.Disabled))
                  == (DrawItemState.Grayed | DrawItemState.Disabled));  // true

0 0 0 0 0 0 0 0 1 1 0    // binary value of disabled and grayed

0 0 0 0 0 0 0 0 1 1 0    // binary value of disabled and grayed

0 0 0 0 0 0 0 0 1 1 0    // result is same value as disabled and grayed

Лично я думаю, что проще проверить значения флагов, используя HasFlag:

Console.WriteLine(state.HasFlag(DrawItemState.Grayed));  // true

Обратите внимание, что если есть только одно значение, то == будет работать, но для перечисления "flags", которое поддерживает битовую комбинацию, это никогда не гарантируется.

var state = DrawItemState.Grayed;

Console.WriteLine(state == DrawItemState.Grayed);  // true
...