Validating Bit-Coded Enum Values

Question
What’s the recommended way to check bit-coded enum values?

Answer
The following code demonstrates how to test bit-coded enum values.

FileProperty fileProperty = GetFileProperties();

// Incorrect. This will fail if fileProperty has more than one bit set.
if ( fileProperty == FileProperty.Hidden ) {
    ...
}

// Also incorrect. This cannot test multiple bits at once.
if ( (fileProperty & FileProperty.Hidden ) != 0 ) {
    ...
}

// The correct way.
if ( (fileProperty & FileProperty.Hidden) == FileProperty.Hidden ) {
    ...
}

// An example that checks whether a file is System AND Hidden.
FileProperty property = FileProperty.System | FileProperty.Hidden;
if ( (fileProperty & property) == property ) {
    ...
}

Validating Enum Values

Question
Should non-bit-coded enum values be validated when passed to properties or methods as arguments?

Answer
Yes, always validate these values.

Comments
Why? Using an enum parameter only guarantees the value being passed in is an integer. It doesn’t guarantee the value is one of the constants defined in the enum, and it’s possible to define invalid enum values. For example:

DayOfTheWeek dayOfWeek = (DayOfTheWeek) 100;

Example
Here’s an example of how to properly implement a property that takes and returns enum members with no invalid values.

private DayOfTheWeek weekDay = DayOfTheWeek.Sunday;

public DayOfTheWeek WeekDay {
    get {
        return weekDay;
    }
    set {
        if ( value < DayOfTheWeek. Sunday || value > DayOfTheWeek.Saturday ) {
            throw new ArgumentException("Invalid day of the week.");
        weekDay = value;
        }
    }
}

Base Type for Enums

Problem
You want to know when it’s okay to specify the base type for an enumeration.

Solution
As a general rule, you should avoid specifying a base type for enums. Instead, rely on the default Int32 base type.

Comments
There is an exception, of course. You may have a justified reason to specify a non-default base type. For example, let’s say you plan on creating large arrays of enum values. In this case, it’s perfectly valid to use Byte or Int16 as the base type. Just be sure, however, to never use a non-CLS-compliant integer type, like UInt32 or UInt64, as the base type.

Example

// Using a 16-bit enum to save memory.
public enum Authorization : short {
    Pending,
    Processing,
    Complete
}

Flags Attribute for Enum Types

Problem
You want to know how to define enum types that contain a collection of flags instead of single values.

Solution
Mark them with the Flags attribute.

Comments
These types of enums are usually manipulated using bitwise operators. For example…

Example

using System;

namespace Playground
{
    internal static class Program
    {
        [Flags]
        private enum Colors
        {
            Red = 1,
            Blue = 2,
            Green = 4,
            Yellow = 8
        }

        public static void Main()
        {
            var textRepresentation = (Colors.Blue | Colors.Green).ToString();
            Console.WriteLine(textRepresentation);
            // Output is Blue, Green.
        }
    }
}