Private value in C# flags enumeration

I'm creating a flags enumeration in C#, similar to the following:

    [Flags]
    public enum DriversLicenseFlags
    {
        None = 0,

        Suspended = 1 << 1,
        Revoked   = 1 << 2,

        Restored  = 1 << 3,
        SuspendedAndRestored = Suspended | Restored,
        RevokedAndRestored   = Revoked   | Restored,
    }

A couple notes about my intentions here:

  • Suspended and Revoked are unique states that can, but don't necessarily lead to a restore.
  • Restored should only be possible if the user has also been Suspended or Revoked (or both). It's important to track specifically which event was the precursor to the restore.
  • A license can be both Suspended and Revoked (and Restored)

Also, I'm trying to stick to suggestions made in MSDN's Designing Flags Enumerations. In particular:

  • Consider providing special enumeration values for commonly used combinations of flags.
    • SuspendedAndRestored and RevokedAndRestored will both be common.
  • Avoid creating flags enumerations when certain combinations of values are invalid.
    • This is my problem, because Restored is not valid unless at least one of Suspended and Revoked is set.

Ideally, I'd like a value for Restored to be present in the enum for internal usage, but only available to set publicly via some valid combination. Unfortunately, internal isn't a valid modifier for enum values.

I've thought of a few alternatives, but each seems to have drawbacks:

  1. Keep Restored as a public value, note the limitations in comments and do a precondition check for invalid combinations on public APIs.

    This would work, and is likely the solution I will go with. However, it seems like their should be a cleaner solution.

  2. Use an enhanced, java-like enum as described here and define Restored as internal static.

    This would also work, but feels like overkill because I don't need any of the other functionality at this point.

  3. Don't define Restored as a value, but reserve the value for OR'ing, and for checking the value in consuming methods. i.e.:

    internal const int RestoredFlag = 1 

This feels hacky me, both in how it's defined and how it will be used internally.

6
задан Community 23 May 2017 в 12:19
поделиться