![]() |
Languages »
C# »
Enumerations
Intermediate
License: The Code Project Open License (CPOL)
Everyday programming techniques - C# EnumsBy Hugo PEREIRAThis article reviews basic and advanced programming with enums (flags, bit flags cast, and more). |
C# (C# 1.0, C# 2.0, C# 3.0), .NET, Dev
|
|
Advanced Search |
|
|
|
||||||||||||||||

This article will review some basic concepts of the C# language and present examples of advanced programming with enums. The aim is to review enums in detail and to use this concept of the language to produce better quality code in everyday programming.
The enum keyword is used to declare an enumeration; there exists two enum types:
The default underlying type is int. By default, the first enumerator has the value 0 and the value of each element is increased by 1.
enum Color {White, Red, Blue, Green, Black};
The Color enum enumerators are White=0, Red=1,…, Black= 4.
You can override the first enumerator value, for example:
enum Color {White=2, Red, Blue, Green, Black};
Now, the enumerator values are White=2, Red=3,…, Black= 6.
You also can set every enumerator's value.
To extract the default values from an enum, you can use the default keyword, for example:
enum Color {White=2, Red, Blue, Green, Black};
Color myColor = default(Color);
Console.WriteLine("Color = {0}", myColor);
Here is the output:
Color = 2
Each enum has an underlying type; the default type is int, and the approved types are byte, sbyte, short, ushort , uint, long, and ulong. For example, if you want to use less memory for an enum, you can use byte, or long to increase the size for enumerator values.
// Use byte enumerators
enum Color :byte { White, Red, Blue, Green, Black };
// Use long enumerators
enum Limite :long {Down = 0L, Up = 2147483648L};
You can assign any value in the range of the underlying enum to a variable of type Colors, they are not limitated to named constants.
Using enumerators as bit flags can be useful to combine options or settings without creating separate properties. To enable bitwise combination of enumerators, you must start by setting up each enumerator with a bit mask flag. Look at the binary comments to understand why we are using 1, 2, 4.
public enum DocumentPermissions {
Modify = 1, // 001
Read = 2, // 010
Write = 4, // 100
FullControl = Modify | Read | Write // 111
};
So, if we want to check if an enum variable "permission" is equal to DocumentPermissions.Modify, DocumentPermissions.FullControl, or DocumentPermissions.Read, we can use the code below:
public class PermissionValidator {
public static bool CheckModify (DocumentPermissions doc) {
return ((int)doc & (int)DocumentPermissions.Modify) == 1;
}
}
// Modify
DocumentPermissions permission = DocumentPermissions.Modify;
Console.WriteLine ("Result 1 = {0}", PermissionValidator.CheckModify (permission));
// FullCOntrol
permission = DocumentPermissions.FullControl;
Console.WriteLine ("Result 2 = {0}", PermissionValidator.CheckModify (permission));
// Read permission = DocumentPermissions.Read;
Console.WriteLine ("Result 3 = {0}", PermissionValidator.CheckModify (permission));
Here is the output:
Result 1 = True
Result 2 = True
Result 3 = False
Now, we will see a logical operation using '&', the logical operation 'AND'. The operation below uses the same values as the code:

Below is an illustration of the Flags attribute using ToString():
[Flags]
public enum DocumentPermissionsFlag {
Modify = 1, // 001
Read = 2, // 010
Write = 4, // 100
FullControl = Modify | Read | Write // 111
};
Without the Flags attribute, calling ToString() produces the following output:
DocumentPermissions permission =
DocumentPermissions.Modify | DocumentPermissions.Write;
Console.WriteLine("Output 1 = {0}", permission.ToString());
Here is the output:
Output 1 = 5
Now, with the Flags attribute, ToString() produces the following output:
DocumentPermissionsFlag permissionFlag =
DocumentPermissionsFlag.Modify | DocumentPermissionsFlag.Write;
Console.WriteLine ("Output 2 = {0}", permissionFlag.ToString());
Here is the output:
Output 2 = Modify, Write
The casting of a string or an int to an enum can be useful to convert data from different data sources. For example, data from a database, XML file attributes, or a web page query string can be bound to an enum.
Below is an example of a string to enum conversion; this cast is performed using the static method Parse from the enum object:
DocumentPermissions permission =
(DocumentPermissions)Enum.Parse (typeof (DocumentPermissions), "Write");
Console.WriteLine ("Output {0}", permission.ToString ());
Now, an example of an int to enum conversion; it uses the ToObject method of the enum object. With the int type, you can also use a simple cast (see equivalent to):
permission =
(DocumentPermissions)Enum.ToObject (typeof (DocumentPermissions), 4);
Console.WriteLine ("Output {0}", permission.ToString ());
// Equivalent to
permission = (DocumentPermissions) 4;
The two previous calls may cause an error if the string or the int were not an element of the enum. To check whether an item is not part of an enum, we can use the static method IsDefined from the Enum class.
In the example below, I use IsDefined to control if the element is contained in the enum; in this case, I throw a ArgumentOutOfRangeException.
Now, we will discuss about a generic cast. To create a method that casts a string or an integer to any type of enum, we can use the T keyword.
Since version 2 of the .NET Framework, it is possible to have one method that returns the deferent’s data type. Below is an example with the type string.
public static T CastToEnum<T> (string name) {
if (Enum.IsDefined (typeof (T), name)) {
return (T)Enum.Parse (typeof (T), name);
}
else { //No enum for string name
throw new
ArgumentOutOfRangeException (
string.Format ("{0}...{1}", name, typeof (T).ToString()));
}
}
//Animal enum
public enum Animal {
Dog = 1,
Cat,
Mouse,
Bird,
Tiger
};
// Use EnumHelper
Animal animal = EnumHelper.CastToEnum<Animal> ("Dog");
Console.WriteLine ("Output {0}", animal.ToString ());
Here is the output:
Output Dog
In the source code of the article, you will find a class EnumHelper that contains two methods that cast an int and a string to any type of enums.
We have the possibility to enumerate an enumerator’s names and values using the Enum class; with the same methods, you can count the number of elements from the enum. Below is an example of using the GetNames static method from the Enum class:
foreach (string name in Enum.GetNames (typeof (Animal))) {
System.Console.WriteLine (name);
}
Here is the output:
Dog
Cat
Mouse
Bird
Tiger
Now, an example enumerating the enum values using GetValues:
foreach (int name in Enum.GetValues (typeof (Animal))) {
System.Console.WriteLine (name);
}
Here is the output:
1
2
3
4
5
The same method can count the items on an enum. The GetValues returns an array containing the values of the items defined in the enumeration. We can then check the array’s length.
System.Console.WriteLine ("Count = {0}",
Enum.GetValues (typeof (Animal)).Length);
Here is the output:
Count = 5
You can easily create a « switch » from an enum variable with Visual Studio 2005-2008.
Animal animal;
Note: Visual Studio create the enum skeleton and selects the "switch_on" text.
switch (switch_on) {
default:
}
Note: The editor automatically creates the cases for the switch.
switch (animal) {
case Animal.Dog:
break;
case Animal.Cat:
break;
case Animal.Mouse:
break;
case Animal.Bird:
break;
case Animal.Tiger:
break;
default:
break;
}
Be attentive to the default path; in many cases, the switch enum does not require a default path.
Using enums instead of hard coded values can improve your coding quality, but be careful of design mistakes.
None or NoValue, set their value to 0.[Flags] attribute to bit flag enums.[Flags] attribute to standard enums.I hope that this article will help you to improve your code; if you have any questions or remarks, please add a comment. I will respond as soon as possible.
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 26 Nov 2008 Editor: Smitha Vijayan |
Copyright 2008 by Hugo PEREIRA Everything else Copyright © CodeProject, 1999-2009 Web13 | Advertise on the Code Project |