Home
Search
C# enum Flags Attribute ExamplesUse the Flags attribute on an enum. See how to use switch and bitwise operators together.
Flags, enum. Flags allow an enum value to contain many values. An enum type with the [Flags] attribute can have multiple constant values assigned to it.
With Flags, it is still possible to test enums in switches and if-statements. Flags can be removed or added. We can specify multiple flags with the "or" operator.
Enum
Attribute
First example. This program introduces a FileAttributes enum. We use the values 0, 1, 2, 4 to indicate the underlying bits for each value—we should double each value to avoid conflicts.
Operators We use bitwise operators, like OR and AND, with enum flags. We use "NOT" to remove a flag from an enum.
C# program that uses enum flags
using System; class Program { [Flags] enum FileAttributes { None = 0, Cached = 1, Current = 2, Obsolete = 4, } static void Main() { // Create new enum instance with flags. Console.WriteLine("SET CACHED AND CURRENT FLAGS"); var attributes = FileAttributes.Cached | FileAttributes.Current; // See if current flag is set. if ((attributes & FileAttributes.Current) == FileAttributes.Current) { Console.WriteLine("File is current"); } // See if obsolete flag is not set. if ((attributes & FileAttributes.Obsolete) != FileAttributes.Obsolete) { Console.WriteLine("File is not obsolete"); } // Remove current flag. Console.WriteLine("REMOVE CURRENT FLAG"); attributes &= ~FileAttributes.Current; // See if current flag is set again. if ((attributes & FileAttributes.Current) != FileAttributes.Current) { Console.WriteLine("File is not current"); } } }
SET CACHED AND CURRENT FLAGS File is current File is not obsolete REMOVE CURRENT FLAG File is not current
Example, switch. This example shows an enum with 6 bit flags in it. Notice how the word [Flags] appears on top of the enum, with the square brackets.
Switch The method Check shows how to switch on enum flags. We act on combinations of the flags in a constant-time expression.
Switch
Note The "|" operator is used in the cases. This means the values are combined.
Values The values 0x0, 0x1, 0x2, 0x4 are powers of 2. Powers of 2 contain one bit set, moving from the first to the final bit.
Tip You could use the decimal values, 0, 1, 2, 4, 8 instead. This might be clearer.
C# program that uses enum flags, switch
using System; class Program { [Flags] enum RenderType { None = 0x0, DataUri = 0x1, GZip = 0x2, ContentPage = 0x4, ViewPage = 0x8, HomePage = 0x10 // Next two values could be 0x20, 0x40 } static void Main() { // 1. // Set the first type. RenderType type1 = RenderType.ContentPage; // 2. // Set the second type if the condition matches. if (true) { type1 |= RenderType.GZip; } // 3. // Check the enum flags. Check(type1); // 4. // Set a new enum in three statements. RenderType type2 = RenderType.ViewPage; type2 |= RenderType.DataUri; type2 |= RenderType.GZip; // 5. // See if the enum contains this flag. if ((type2 & RenderType.DataUri) == RenderType.DataUri) { Console.WriteLine("True"); } // 6. // See if the enum contains this flag. if ((type2 & RenderType.ContentPage) == RenderType.ContentPage) { throw new Exception(); } // 7. // Check the enum flags. Check(type2); } static void Check(RenderType type) { // Switch on the flags. switch (type) { case RenderType.ContentPage | RenderType.DataUri | RenderType.GZip: { Console.WriteLine("content, datauri, gzip"); break; } case RenderType.ContentPage | RenderType.GZip: // first match { Console.WriteLine("content, gzip"); break; } case RenderType.ContentPage: { Console.WriteLine("content"); break; } case RenderType.ViewPage | RenderType.DataUri | RenderType.GZip: // second match { Console.WriteLine("view, datauri, gzip"); break; } case RenderType.ViewPage | RenderType.GZip: { Console.WriteLine("view, gzip"); break; } case RenderType.ViewPage: { Console.WriteLine("view"); break; } case RenderType.HomePage | RenderType.DataUri | RenderType.GZip: { Console.WriteLine("home, datauri, gzip"); break; } case RenderType.HomePage | RenderType.GZip: { Console.WriteLine("home, gzip"); break; } case RenderType.HomePage: { Console.WriteLine("home"); break; } } } }
content, gzip True view, datauri, gzip
Notes, operators. The "|=" operator actually adds a flag to the enum, so the enum now contains two flag bits. You can use "|=" to add bits, while & will test bits without setting them.
And Bitwise AND returns a value with 1 in the targeted bit if both values contain the bit.
And
Tip You can therefore AND two values together and test the result for the target bit.
Also Bitwise OR, "|", returns 1 in the bit if either value has it set. It can be used in switch, setting all bits in the cases.
Bitwise Or
A discussion. When you are using enum flags, you are concerned about performance. The switch compiles to a jump table which is faster than if-else chains.
Switch Enum
Also Using bitwise flags on your enum has severe limitations. It can help improve certain code that has few flags that are often combined.
But You cannot extend enum flags as much as a regular enum. If you need 100 enum values, you should use separate integer enums.
A summary. Enum flags represent more complex constants and combinations. We used bitwise flags with enums. We can assign, add, set, check, and switch on flags.
Home
© 2007-2021 sam allen. see site info on the changelog