Navigate back home
GalaSoft Laurent Bugnion
.NET: Using C# generics to extract enumerated flags from a numeric value.
Introduction:
The CFlagsExtracter class takes two parameters: An enumeration type and an integer value (Int32). The enumeration value must be a bit field (aka set of flags). This is ensured by the presence of a FlagsAttribute.
[Flags]
public enum EFlags
{
  eFlag1 = 1,
  eFlag2 = 2,
  eFlag3 = 4,
  eFlag4 = 8,
  eFlag5 = 16,
  eFlag6 = 32,
}
Once the two parameters are known, the class extracts from the integer value the flags set. For example, the decimal value 45 is equal to the binary value 101101, in which the first, third, fourth and sixth flags are set. Corresponding to the EFlags enum above, it means that eFlag1, eFlag3, eFlag4 and eFlag6 are set. In that case, the property aeFlags will contain an array of type EFlags with 4 cells, containing the corresponding enum values.

Using generics:
Generics are a great addition to .NET 2.0. The are similar to C++ templates, but (in my opinion) much easier to understand and to use. They allow to define a class or a method's functionality without knowing what the types of its components (attributes, return value, parameters...) will be. As the name indicates, it allows working in generic ways, and enhance reusability of such components.

Extracting flags:
Checking if a given flag is set in an integer value is very easy when you know how: Make a logical (bitwise) AND between the integer value and the flag value. This will set all the other bits to 0. After that, compare the resulting value with the flag value, et voilĂ  :-)
int iFlagValue = (int) EFlags.eFlag2;
int iTest = iFlagValue & iValue;
if ( iTest == iFlagValue )
{
  // The flag "eFlag2" is set in iValue
}

CFlagsExtracter usage:
In our case, the usage of the CFlagsExtracter class is simple enough:
CFlagsExtracter<EFlags> oExtracter
  = new CFlagsExtracter<EFlags>( iValue );

foreach ( EFlags eFlag in oExtracter.aeFlags )
{
  // Do something
}

Practical example: Getting a file's attributes
The CFlagsExtracter class can be used for example to get a file or a directory's attributes. The attributes (see FileAttributes) are an enumeration marked with the "Flags" attribute, so they are perfectly suitable for this class!
FileInfo fl = new FileInfo( @"d:\temp\test.txt" );
if ( fl.Exists )
{
  CFlagsExtracter<FileAttributes> oFileAttributesExtracter
    = new CFlagsExtracter<FileAttributes>( (int) fl.Attributes );

  foreach ( FileAttributes eAttribute
    in oFileAttributesExtracter.aeFlags )
  {
    Console.WriteLine( eAttribute.ToString() );
  }
}

Source code:
The source code can be downloaded here.

Demo:
This demo only works on AJAX-enabled web browsers. For more information, contact me.
The request's URL is CFlagExtracterClient.ashx?flags=XXX where XXX is an integer value. The server uses a HttpHandler to create an XML response, for example:
<?xml version="1.0" encoding="utf-8" ?>
<flags value="45">
  <flag name="eFlag1" value="1" />
  <flag name="eFlag3" value="4" />
  <flag name="eFlag4" value="8" />
  <flag name="eFlag6" value="32" />
</flags>
Request
 Flag one (1)
 Flag two (2)
 Flag three (4)
 Flag four (8)
 Flag five (16)
 Flag six (32)

Response