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

С программной точки зрения для клиента это является упаковочным параметры и добавление их на URL и проведение POST по сравнению с ПОЛУЧЕНИЕМ. На серверной стороне это оценивает входящие параметры от querystring вместо отправленных байтов. В основном это - промывка.

то, Где могли быть преимущества/недостатки, могло бы быть в том, как определенная клиентская работа платформ с POST и ПОЛУЧАЕТ стандартные программы в их сетевом стеке, а также как веб-сервер имеет дело с теми запросами. В зависимости от Вашей реализации один подход может быть более эффективным, чем другой. Знание, которое вело бы Ваше решение сюда.

, Тем не менее, с точки зрения программиста, я предпочитаю позволять или POST со всеми параметрами в теле или ПОЛУЧЕНИЕ со всеми параметрическими усилителями на URL, и явно игнорировать параметры URL с любым запросом POST. Это избегает беспорядка.

165
задан T.S. 27 January 2015 в 18:24
поделиться

9 ответов

Если вы хотите узнать, есть ли в букве какие-либо буквы в AB вы должны использовать оператор И &. Что-то вроде:

if ((letter & Letters.AB) != 0)
{
    // Some flag (A,B or both) is enabled
}
else
{
    // None of them are enabled
}
121
ответ дан 23 November 2019 в 21:06
поделиться

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

Пример A

if (letter != 0)
{
}

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

Aproach B

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

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

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

if ((letter & Letters.AB) != 0)
{
}
0
ответ дан 23 November 2019 в 21:06
поделиться

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

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) { }

ОБНОВЛЕНИЕ

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

0
ответ дан 23 November 2019 в 21:06
поделиться
if((int)letter != 0) { }
0
ответ дан 23 November 2019 в 21:06
поделиться

Это сработает для вас?

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

С уважением,

Себастьян

2
ответ дан 23 November 2019 в 21:06
поделиться

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

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

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

Это проверяет, что установлены как A, так и B, и игнорирует, установлены ли какие-либо другие флаги.

 if ((буква & Letters.A) == Letters.A || (буква & Letters.B) == Letters.B)

Это проверяет, установлены ли либо A, либо B, и игнорирует, установлены ли другие флаги.

Это можно упростить до:

if(letter & Letters.AB)

Здесь C для двоичных операций; это должно быть несложно применить к C #:

enum {
     A = 1,
     B = 2,
     C = 4,
     AB = A | B,
     All = AB | C,
};

int flags = A|C;

bool anything_and_a = flags & A;

bool only_a = (flags == A);

bool a_and_or_c_and_anything_else = flags & (A|C);

bool both_ac_and_anything_else = (flags & (A|C)) == (A|C);

bool only_a_and_c = (flags == (A|C));

Между прочим, имя переменной в примере вопроса - это единственная «буква», что может означать, что она представляет только одну букву; пример кода проясняет, что это набор возможных букв и что разрешено несколько значений, поэтому рассмотрите возможность переименования переменной «письма».

8
ответ дан 23 November 2019 в 21:06
поделиться

Если это вас действительно раздражает, вы можете написать такую ​​функцию:

public bool IsSet(Letters value, Letters flag)
{
    return (value & flag) == flag;
}

if (IsSet(letter, Letters.A))
{
   // ...
}

// If you want to check if BOTH Letters.A and Letters.B are set:
if (IsSet(letter, Letters.A & Letters.B))
{
   // ...
}

// If you want an OR, I'm afraid you will have to be more verbose:
if (IsSet(letter, Letters.A) || IsSet(letter, Letters.B))
{
   // ...
}
12
ответ дан 23 November 2019 в 21:06
поделиться

Я использую методы расширения для напишите такие вещи:

if (letter.IsFlagSet(Letter.AB))
    ...

Вот код:

public static class EnumExtensions
{
    private static void CheckIsEnum<T>(bool withFlags)
    {
        if (!typeof(T).IsEnum)
            throw new ArgumentException(string.Format("Type '{0}' is not an enum", typeof(T).FullName));
        if (withFlags && !Attribute.IsDefined(typeof(T), typeof(FlagsAttribute)))
            throw new ArgumentException(string.Format("Type '{0}' doesn't have the 'Flags' attribute", typeof(T).FullName));
    }

    public static bool IsFlagSet<T>(this T value, T flag) where T : struct
    {
        CheckIsEnum<T>(true);
        long lValue = Convert.ToInt64(value);
        long lFlag = Convert.ToInt64(flag);
        return (lValue & lFlag) != 0;
    }

    public static IEnumerable<T> GetFlags<T>(this T value) where T : struct
    {
        CheckIsEnum<T>(true);
        foreach (T flag in Enum.GetValues(typeof(T)).Cast<T>())
        {
            if (value.IsFlagSet(flag))
                yield return flag;
        }
    }

    public static T SetFlags<T>(this T value, T flags, bool on) where T : struct
    {
        CheckIsEnum<T>(true);
        long lValue = Convert.ToInt64(value);
        long lFlag = Convert.ToInt64(flags);
        if (on)
        {
            lValue |= lFlag;
        }
        else
        {
            lValue &= (~lFlag);
        }
        return (T)Enum.ToObject(typeof(T), lValue);
    }

    public static T SetFlags<T>(this T value, T flags) where T : struct
    {
        return value.SetFlags(flags, true);
    }

    public static T ClearFlags<T>(this T value, T flags) where T : struct
    {
        return value.SetFlags(flags, false);
    }

    public static T CombineFlags<T>(this IEnumerable<T> flags) where T : struct
    {
        CheckIsEnum<T>(true);
        long lValue = 0;
        foreach (T flag in flags)
        {
            long lFlag = Convert.ToInt64(flag);
            lValue |= lFlag;
        }
        return (T)Enum.ToObject(typeof(T), lValue);
    }

    public static string GetDescription<T>(this T value) where T : struct
    {
        CheckIsEnum<T>(false);
        string name = Enum.GetName(typeof(T), value);
        if (name != null)
        {
            FieldInfo field = typeof(T).GetField(name);
            if (field != null)
            {
                DescriptionAttribute attr = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
                if (attr != null)
                {
                    return attr.Description;
                }
            }
        }
        return null;
    }
}
58
ответ дан 23 November 2019 в 21:06
поделиться

Как насчет

if ((letter & Letters.AB) > 0)

?

3
ответ дан 23 November 2019 в 21:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: