Как определить, имеет ли значение Enum одно или несколько значений, с которыми оно сравнивается?
У меня есть Enum, отмеченный атрибутом [Flags] следующим образом:
[Flags]
public enum Tag : int
{
None = 0,
PrimaryNav = 1,
HideChildPages = 2,
HomePage = 4,
FooterLink = 8
}
В sitemapnodes в моей карте сайта я сохраняю значение int для комбинации тегов в качестве атрибута.
Что мне нужно сделать, это проверить, имеет ли node любой один или несколько тегов, например. Tag.PrimaryNav | Tag.HomePage.
Я борюсь с необходимой логической логикой, чтобы определить, имеет ли значение Enum одно или несколько значений, с которыми оно сравнивается.
Извините, если это не ясно. При необходимости я могу предоставить дополнительную информацию.
Ответы
Ответ 1
Вы можете сделать это, объединив значения с |
и проверив с помощью &
.
Чтобы проверить, содержит ли значение какой-либо из тегов:
if ((myValue & (Tag.PrimaryNav | Tag.HomePage)) != 0) { ... }
|
объединяет проверенные вами переименования (поразрядные) и теги &
с помощью побитовой маскировки - если результат не равен нулю, у него есть хотя бы один из них.
Если вы хотите проверить, установлены ли оба из них, вы также можете сделать это:
Tag desiredValue = Tag.PrimaryNav | Tag.HomePage;
if ((myValue & desiredValue) == desiredValue) { ... }
Здесь мы маскируем все, что нам неинтересно, и проверяем, что итоговое значение равно тому, что мы заботимся (мы не можем использовать != 0
, как раньше, потому что это будет соответствовать либо значению, заинтересованы в обоих).
Некоторые ссылки:
Ответ 2
Вы можете использовать метод HasFlag, чтобы избежать необходимости в логической логике,
Tag Val = (Tag)9;
if (Val.HasFlag(Tag.PrimaryNav))
{
Console.WriteLine("Primary Nav");
}
if(Val.HasFlag(Tag.HomePage))
{
Console.WriteLine("Home Page");
}
Ответ 3
Для побитовых (Flags
) перечислений "любой" тест равен!= 0, поэтому:
const Tag flagsToLookFor = Tag.PrimaryNav | Tag.HomePage;
if ((node.Tag & flagsToLookFor) != 0) {
// has some cross-over with PrimaryNav or HomePage (and possibly others too)
}
Ответ 4
var someEnumValue = Tag.PrimaryNav | Tag.HomePage;
Чтобы проверить, содержит ли перечисление заданное значение:
if ((someEnumValue & Tag.PrimaryNav) == Tag.PrimaryNav)
{
}
Ответ 5
var tag = Tag.HideChildPages | Tag.PrimaryNav;
If ((tag & Tag.PrimaryNav) == Tag.PrimaryNav) {
// Tag.PrimaryNav set.
}
Ответ 6
Вы можете использовать библиотеку Jon Skeet Unconstrained Melody:
var someEnumValue = Tag.PrimaryNav | Tag.HideChildPages;
someEnumValue.HasAny(Tag.PrimaryNav | Tag.HomePage); // Returns true
Ответ 7
Вы можете использовать этот метод расширения для перечисления для любого типа перечислений:
public static bool IsSingle(this Enum value)
{
var items = Enum.GetValues(value.GetType());
var counter = 0;
foreach (var item in items)
{
if (value.HasFlag((Enum)item))
{
counter++;
}
if (counter > 1)
{
return false;
}
}
return true;
}