Enum.HasFlag

  • 3 minutes to read
  • edit

An enumerated type, also called an enumeration (or just an enum for short), is simply a way to create a numeric type restricted to a predetermined set of valid values with meaningful names for those values. While most enumerations represent discrete values, or well-known combinations of those values, sometimes you want to combine values in an arbitrary fashion. These enumerations are known as flags enumerations because the values represent flags which can be set or unset. To combine multiple enumeration values, you use the logical OR operator.

For example, consider the following:

public enum FileAccess
{
   None = 0,
   Read = 1,
   Write = 2,
}

class Program
{
    static void Main(string[] args)
    {
        FileAccess access = FileAccess.Read | FileAccess.Write;
        Console.WriteLine(access);
    }
}

The output of this simple console application is:

The value 3 is the numeric value associated with the combination of FileAccess.Read and FileAccess.Write. Clearly, this isn’t the best representation. What you really want is for the output to look like:

To achieve this result, you simply add the Flags attribute to the enumeration. The Flags attribute changes how the string representation of the enumeration value is displayed when using the ToString() method.

Although the .NET Framework does not require it, enumerations that will be used to represent flags should be decorated with the Flags attribute since it provides a clear indication of intent.

One “problem” with Flags enumerations is determining when a particular flag is set. The code to do this isn’t particularly difficult, but unless you use it regularly it can be easy to forget. To test if the access variable has the FileAccess.Read flag set, you would use the following code:

(access & FileAccess.Read) == FileAccess.Read

Starting with .NET 4, a HasFlag static method has been added to the Enum class which allows you to easily perform these tests:

access.HasFlag(FileAccess.Read)

This method follows one of the “themes” for the .NET Framework 4, which is to simplify and reduce the amount of boilerplate code like this you must write.

Comments