Подтвердить что ты не робот

Как определить, имеет ли значение 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 одно или несколько значений, с которыми оно сравнивается.

Извините, если это не ясно. При необходимости я могу предоставить дополнительную информацию.

4b9b3361

Ответ 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;
    }