7

Does any have a more elegant way of doing this?

[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;
        }
    }
} 

I know there is probably a simple answer and I'm just way over thinking it...

EDIT: The enum was incorrect as pointed out in one of the answers. This was only in this example and not in the actual code.

Adam Driscoll
  • 9,030
  • 7
  • 57
  • 98
  • Take a look at this http://stackoverflow.com/questions/5850873/enum-hasflag-why-no-enum-setflag – Vasea Aug 05 '11 at 15:14
  • what about a ternary operator instead of setting property? –  Aug 05 '11 at 15:15
  • 2
    @Adam: I got a discussion with guys arround what is "elegant" code here on SO. The elegant code is the code that is easy to read and understand. So I think you have already an elegant solution. – Tigran Aug 05 '11 at 15:16
  • True, but if you have a lot of these things, a more compact representation may be more desirable. But you can always just #region them and compact them in the IDE, so, yeah, whatever. – i_am_jorf Aug 05 '11 at 15:23

5 Answers5

8

I mean, you could do:

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

But I think your solution is fine.

i_am_jorf
  • 51,120
  • 15
  • 123
  • 214
6

Well, you could use a conditional:

_myFlags = value ? _myFlags | SomeFlaggedEnum.Value1
                 : _myFlags & ~SomeFlaggedEnum.Value1;
Jon Skeet
  • 1,261,211
  • 792
  • 8,724
  • 8,929
3

It looks like it'd get pretty ugly if you had a property per flag for setting it, assuming you'll have more than 3 flags. Would it not be easier to go for a single method where you can say which flags to set?

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

EnableFlag(SomeFlaggedEnum.Value1, true);
Mark H
  • 13,471
  • 4
  • 26
  • 45
2

Your setter is fine.

The issue is that using FlagsAttribute doesn't make the compiler choose useful values for using the enum members as flags. SomeFlaggedEnum.Value1 is zero, because it's the first declared value in the enumeration, and so it doesn't represent a bit flag at all.

Try

[Flags]
public enum SomeFlaggedEnum
{
    Value1 = 1,
    Value2 = 2,
    Value3 = 4
}
Ben Voigt
  • 260,885
  • 36
  • 380
  • 671
1

Make a generic setter for flags (there is already a generic "HasFlag" in the Enum class, but an extension like this will complement it.

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

Once you have that, you can make properties for each flag (but that quickly gets messy), or simply delegate getting and setting flags to HasFlag/SetFlag

Anders Forsgren
  • 9,992
  • 4
  • 34
  • 70