Как определить, имеет ли значение Enum одно или несколько значений, с которыми сравнивается? - PullRequest
13 голосов
/ 09 марта 2010

У меня есть Enum, помеченный атрибутом [Flags] следующим образом:

[Flags]
public enum Tag : int
{
    None = 0,
    PrimaryNav = 1,
    HideChildPages = 2,
    HomePage = 4,
    FooterLink = 8
}

На sitemapnodes в моем sitemap я храню значение int для комбинации тегов в качестве атрибута.

Мне нужно проверить, есть ли у узла любой одного или нескольких тегов, например, Tag.PrimaryNav | Tag.HomePage.

Я борюсь с необходимой логической логикой, чтобы определить, имеет ли значение Enum одно или несколько значений, с которыми оно сравнивается.

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

Ответы [ 7 ]

27 голосов
/ 09 марта 2010

Вы можете сделать это, комбинируя значения с | и проверяя с помощью &.

Чтобы проверить, содержит ли значение либо тегов:

if ((myValue & (Tag.PrimaryNav | Tag.HomePage)) != 0) { ... }

| объединяет тестируемые перечисления (побитовые) и & тесты с помощью побитовой маскировки - если результат не равен нулю, у него установлен хотя бы один из них.

Если вы хотите проверить, установлены ли для них оба , вы также можете сделать это:

Tag desiredValue = Tag.PrimaryNav | Tag.HomePage;
if ((myValue & desiredValue) == desiredValue) { ... }

Здесь мы маскируем все, что нас не волнует, и проверяем, что полученное значение равно тому, о чем мы делаем (мы не можем использовать != 0, как раньше, потому что это будет либо значение, и здесь нас интересует и ).

Некоторые ссылки:

9 голосов
/ 09 марта 2010

Вы можете использовать метод HasFlag, чтобы избежать необходимости в логической логике,

Tag Val = (Tag)9;

if (Val.HasFlag(Tag.PrimaryNav))
{
    Console.WriteLine("Primary Nav");
}

if(Val.HasFlag(Tag.HomePage))
{
    Console.WriteLine("Home Page");
}
2 голосов
/ 09 марта 2010

Для побитовых (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) 
}
1 голос
/ 28 сентября 2016

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

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;
    }
1 голос
/ 09 марта 2010

Вы можете использовать библиотеку Джона Скита Без ограничений :

var someEnumValue = Tag.PrimaryNav | Tag.HideChildPages;
someEnumValue.HasAny(Tag.PrimaryNav | Tag.HomePage); // Returns true
1 голос
/ 09 марта 2010
var tag = Tag.HideChildPages | Tag.PrimaryNav;

If ((tag & Tag.PrimaryNav) == Tag.PrimaryNav) {
    // Tag.PrimaryNav set.
}
1 голос
/ 09 марта 2010
var someEnumValue = Tag.PrimaryNav | Tag.HomePage;

Чтобы проверить, содержит ли перечисление заданное значение:

if ((someEnumValue & Tag.PrimaryNav) == Tag.PrimaryNav)
{

}
...