Search code examples
c#enum-flags

How should I represent a value of None when a [Flags] enum type doesn't define it?


While working with XNA today, I noticed that one of the enum types that uses [Flags] did not have a None = 0 value:

[Flags]
public enum Buttons
{
    DPadUp = 1,
    DPadDown = 2,
    DPadLeft = 4,
    DPadRight = 8,
    Start = 16,
    Back = 32,
    LeftStick = 64,
    RightStick = 128,
    LeftShoulder = 256,
    RightShoulder = 512,
    BigButton = 2048,
    A = 4096,
    B = 8192,
    X = 16384,
    Y = 32768,
    LeftThumbstickLeft = 2097152,
    RightTrigger = 4194304,
    LeftTrigger = 8388608,
    RightThumbstickUp = 16777216,
    RightThumbstickDown = 33554432,
    RightThumbstickRight = 67108864,
    RightThumbstickLeft = 134217728,
    LeftThumbstickUp = 268435456,
    LeftThumbstickDown = 536870912,
    LeftThumbstickRight = 1073741824,
}

According to MSDN regarding the proper use of the [Flags] attribute:

Do name the zero value of flags enumerations None. For a flags enumeration, the value must always mean all flags are cleared.

If I wanted to indicate a value where no buttons are pressed, would it go against the intent of the enum type to use a value of 0 and cast it to Buttons? According to the design guidelines, it should have this value, but it doesn't.


Solution

  • Yes. Since it is a Flags enum, the state of none of the possible values being set is going to be (Buttons)0 (or default(Buttons) if you'd prefer to indicate it in some way that reflects the type directly in your code), whether the designer of the type assigned a name to it or not.

    Consider that if we can express "no button that isn't the A button is pressed and also the A button isn't pressed" through Buttons.A & ~Buttons.A and the result will be (Buttons)0. The "no button pressed" state is already 0.

    (The one justification I can think of for leaving out None is that you were intending that a type is never used in a case where None is the value pressed. E.g., you are only using this for code that reacts to a button being pressed, and hence None never comes up. Even then one can find using the None/0 value useful in code, but it can mean that leaving it unnamed is more reasonable).