Как проверить, установлены ли какие-либо флаги комбинации флагов? - PullRequest
158 голосов
/ 27 августа 2009

Допустим, у меня есть это перечисление:

[Flags]
enum Letters
{
     A = 1,
     B = 2,
     C = 4,
     AB = A | B,
     All = A | B | C,
}

Чтобы проверить, установлен ли, например, AB, я могу сделать следующее:

if((letter & Letters.AB) == Letters.AB)

Есть ли более простой способ проверить, установлены ли какие-либо флаги объединенной постоянной флага, чем следующие?

if((letter & Letters.A) == Letters.A || (letter & Letters.B) == Letters.B)

Не могли бы вы, например, поменять & с чем-то?

Не слишком стабильно, когда дело доходит до бинарных вещей вроде этого ...

Ответы [ 16 ]

2 голосов
/ 27 августа 2009

Будет ли это работать для вас?

if ((letter & (Letters.A | Letters.B)) != 0)

С уважением,

Sebastiaan

0 голосов
/ 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;
}
0 голосов
/ 29 июля 2016

Извините, но я покажу это в VB:)

   <Flags()> Public Enum Cnt As Integer
        None = 0
        One = 1
        Two = 2
        Three = 4
        Four = 8    
    End Enum

    Sub Test()
    Dim CntValue As New Cnt
    CntValue += Cnt.One
    CntValue += Cnt.Three
    Console.WriteLine(CntValue)
    End Sub

CntValue = 5 Таким образом, перечисление содержит 1 + 4

0 голосов
/ 27 августа 2009

Я вижу два подхода, которые сработают для проверки любого установленного бита.

Aproach A

if (letter != 0)
{
}

Это работает до тех пор, пока вы не возражаете против проверки всех битов, в том числе и неопределенных!

Aproach B

if ((letter & Letters.All) != 0)
{
}

Это проверяет только определенные биты, пока Letters.All представляет все возможные биты.

Для определенных битов (один или несколько установленных) используйте Aproach B, заменив Letters.All битами, которые вы хотите проверить (см. Ниже).

if ((letter & Letters.AB) != 0)
{
}
0 голосов
/ 27 августа 2009

Вы можете просто проверить, не равно ли значение нулю.

if ((Int32)(letter & Letters.AB) != 0) { }

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

[Flags]
enum Letters
{
    None = 0,
    A    = 1,
    B    = 2,
    C    = 4,
    AB   =  A | B,
    All  = AB | C
}

if (letter != Letters.None) { }

UPDATE

Не прочитал вопрос - исправил первое предложение и просто проигнорировал второе.

0 голосов
/ 27 августа 2009
if((int)letter != 0) { }
...