Изменение флага на основе логического значения - PullRequest
4 голосов
/ 05 августа 2011

Есть ли у кого-нибудь более элегантный способ сделать это?

[Flags]
public enum SomeFlaggedEnum
{
    Value1 = 1,
    Value2 = 2,
    Value3 = 4
}


private SomeFlaggedEnum _myFlags;

public bool EnabledValue1
{
    set 
    {
        if (value)
        {
            _myFlags |= SomeFlaggedEnum.Value1;
        }
        else
        {
            _myFlags &= ~SomeFlaggedEnum.Value1;
        }
    }
} 

Я знаю, что, возможно, есть простой ответ, и я просто слишком задумываюсь над этим ...

РЕДАКТИРОВАТЬ: перечисление было неправильно, как указано в одном из ответов. Это было только в этом примере, а не в реальном коде.

Ответы [ 5 ]

8 голосов
/ 05 августа 2011

Я имею в виду, вы могли бы сделать:

_myFlags = value ? myFlags | SomeFlaggedEnum.Value1 : myFlags & ~SomeFlaggedEnum.Value1;

Но я думаю, что ваше решение в порядке.

6 голосов
/ 05 августа 2011

Ну, вы можете использовать условное выражение:

_myFlags = value ? _myFlags | SomeFlaggedEnum.Value1
                 : _myFlags & ~SomeFlaggedEnum.Value1;
2 голосов
/ 05 августа 2011

Похоже, было бы довольно уродливо, если бы у вас было свойство для флага для его установки, при условии, что у вас будет более 3 флагов. Не будет ли проще выбрать один метод, в котором вы можете указать, какие флаги установить?

public void EnableFlag(SomeFlaggedEnum value, bool set) {
    _myFlags = set ? value | _myFlags : ~value & _myFlags;
}

EnableFlag(SomeFlaggedEnum.Value1, true);
2 голосов
/ 05 августа 2011

С вашим сеттером все в порядке.

Проблема в том, что использование FlagsAttribute не заставляет компилятор выбирать полезные значения для использования членов перечисления в качестве флагов. SomeFlaggedEnum.Value1 - ноль, потому что это первое объявленное значение в перечислении, и поэтому оно совсем не представляет битовый флаг.

Попробуйте

[Flags]
public enum SomeFlaggedEnum
{
    Value1 = 1,
    Value2 = 2,
    Value3 = 4
}
1 голос
/ 05 августа 2011

Создайте универсальный установщик для флагов (в классе Enum уже есть универсальный "HasFlag", но такое расширение дополнит его.

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

Как только вы это сделаете, вы можете создать свойства для каждого флага (но это быстро становится беспорядочным) или просто делегировать получение и установку флагов в HasFlag / SetFlag

...