Должен "или" работать с .Net4 Hasflags: enum.HasFlag (AccessRights.Read | AccessRights.Write) - PullRequest
13 голосов
/ 02 ноября 2011

Я пробую новые функции 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
  }

Ответы [ 4 ]

30 голосов
/ 02 ноября 2011

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

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

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

Если это не достаточно хорошо читается для вас, вы можете посмотреть на мою Неограниченную мелодию проект.Бывает так, что он уже обладает нужной вам функциональностью (как методы расширения в 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)

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

20 голосов
/ 02 ноября 2011

С MSDN :

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

thisInstance And flag = flag

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

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

myAccessRights & (AccessRights.Read | AccessRights.Write) != 0 
3 голосов
/ 02 ноября 2011

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

1 голос
/ 21 декабря 2015

Кроме того, вы можете просто изменить порядок выражения:

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

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

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

EDIT

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

...