C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
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");
}
}
}
Output
SET CACHED AND CURRENT FLAGS
File is current
File is not obsolete
REMOVE CURRENT FLAG
File is not current
Switch: The method Check shows how to switch on enum flags. We act on combinations of the flags in a constant-time expression.
SwitchNote: 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;
}
}
}
}
Output
content, gzip
True
view, datauri, gzip
And: Bitwise AND, which you use with &, returns a value with 1 in the targeted bit if both values contain the bit.
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.
Binary RepresentationAndBitwise OrAlso: 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.