Должен "или" работать с .Net4 Hasflags: enum.HasFlag(AccessRights.Read | AccessRights.Write)

Я пытаюсь использовать новые функции HasFlags и задаюсь вопросом, должно ли работать следующее:

enum.HasFlag(AccessRights.Read | AccessRights.Write)

... потому что он не кажется...

 DBAccessRights rights = (DBAccessRights)permission.PermissionFlags;
  if (rights.HasFlag(DBAccessRights.WikiMode))
  {
     // works
  }


  if (rights.HasFlag(DBAccessRights.WikiMode | DBAccessRights.CreateNew))
  {
     // Doesn't work    
  }

  DBAccessRights flags = DBAccessRights.WikiMode | DBAccessRights.CreateNew;
  if (rights.HasFlag(flags))
  {
     // Doesn't work
  }

Ответ 1

Учитывая документацию, я ожидаю, что для возврата true, если значение имеет оба этих флага.

Если вы хотите проверить, имеет ли ваше значение один из этих флагов, вам понадобится

value.HasFlag(AccessRights.Read) | value.HasFlag(AccessRights.Write)

Если вам это не достаточно хорошо читается, вы можете посмотреть мой проект Unconstrained Melody. Так получилось, что у вас уже есть необходимая функциональность (как методы расширения в Flags.cs):

// Same as value.HasFlag(AccessRights.Read | AccessRights.Write)
value.HasAll(AccessRights.Read | AccessRights.Write)

// Same as value.HasFlag(AccessRights.Read) | value.HasFlag(AccessRights.Write)
value.HasAny(AccessRights.Read | AccessRights.Write)

Это станет более ясным, ИМО. Они также избегали бокса и были бы набраны:)

Ответ 2

От MSDN:

Метод HasFlag возвращает результат следующих Boolean выражение.

thisInstance И флаг = флаг

Для сложного флага, такого как AccessRights.Read | AccessRights.Write, это будет проверять наличие всех "содержащихся" флагов.

Вероятно, вы хотите проверить, присутствует ли какой-либо из флагов, и в этом случае вы можете сделать:

myAccessRights & (AccessRights.Read | AccessRights.Write) != 0 

Ответ 3

Оператор | побитовый или. Это означает, что если Read равно 1 и Write равно 2, значение Read | Write равно 3 (см. Его двоичное представление). Поэтому HasFlag возвращает true, только если ваша переменная enum имеет как Read, так и Write.

Ответ 4

В качестве альтернативы вы можете просто изменить порядок выражения:

//returns true - a bit easier on the eye
(AccessRights.Read | AccessRights.Write).HasFlag(myAccessRights)

Это вернет true, если у вас есть либо Read | Доступ к записи. Это было бы функционально эквивалентно:

//also returns true - as per @Ani answer
myAccessRights & (AccessRights.Read | AccessRights.Write) != 0

ИЗМЕНИТЬ

Как указано в комментариях, первое выражение вернет true, если myAccessRights пуст, а false, если myAccessRights имеет больше, чем просто чтение и запись.