Brush up on using enum values in your programs, which are important to keeping code clean and understandable. Enums are essentially a custom integer type you can use. They allow the C# compiler to greatly improve its error-checking and warn you. Enums help us code better, provided we use them properly.
First things first, and I want to start with looking at some simple enum samples. One usage I have had for enums is using them in a parser, and keeping the current section's type in an enum. I put the enums in a Stack for the parser. You can use a List or Dictionary as well.
class EnumTest1
{
/// <summary>
/// Define an example enum, beginning with the 'None' value.
/// No instance of the enum is created here.
/// </summary>
enum StackTag
{
None, // Assigned 0 automatically.
BoldTag, // 1
ItalicsTag, // 2
HyperlinkTag, // and 3.
};
/// <summary>
/// Show an example of how to use the enum custom type in a collection.
/// </summary>
public EnumTest1()
{
// This example shows a generic object in C# that uses an enum.
// It is an example of how you could use a StackTag enum in a Stack.
Stack<StackTag> stack = new Stack<StackTag>();
stack.Push(StackTag.BoldTag); // Add bold
stack.Push(StackTag.ItalicsTag); // Add italics
StackTag thisTag = stack.Pop(); // Get top tag.
}
}
In your C# code, you always have "names" for the enums. Some names in the following code are "None", "Hidden", and "Visible". These are actually remembered by C# and not compiled out like some variable names. Therefore we can easily print them out in our code and see what they are.
/// <summary>
/// This is a good enum. It will always have a default value.
/// </summary>
enum VisibleType
{
None = 0, // Should be 0!
Hidden = 2, // Can be any number
Visible = 4 // Any number
};
/// <summary>
/// This enum doesn't have a value that is equal to zero.
/// When it is a member value, it will have a value that cannot be checked or printed.
/// </summary>
enum BugEnum
{
Cat = 1,
Dog = 2
};
/// <summary>
/// Show an example of how to display the enum name.
/// </summary>
public void Example_ToString()
{
BugEnum bugEnum = BugEnum.Dog;
VisibleType visEnum = VisibleType.Hidden;
// We have two enums, and we want to display their names.
Console.WriteLine(bugEnum.ToString() + ", " + visEnum.ToString());
// Displays "Dog, Hidden".
}
Just as you can print out the string using ToString of an enum, you can go the opposite direction and get the enum value equal to the string. We must use the Enum.Parse static method here. We also see the typeof operator, which we need to tell Parse what type of enum we require. We also must cast the result.
/// <summary>
/// Show an example of how to get from a string to an enum.
/// </summary>
public void Example_Parse()
{
// We have a string that matches the name of an enum value.
string dogString = "Dog";
// Use the static Parse method to convert it to the enum.
BugEnum bugEnum = (BugEnum)Enum.Parse(typeof(BugEnum), dogString);
if (bugEnum == BugEnum.Dog)
{
// The string was converted into an enum. They are both Dog now.
Console.WriteLine("Both are dog values.");
}
}
Switch is ideal for when you want to see if an enum value is in one subset of an enum's range. What the next example shows is a way to switch on our StackTag enums, and see if it is a formatting enum (one that changes the text styling).
/// <summary>
/// Example enum of tag types.
/// </summary>
public enum StackTag
{
None,
BoldTag,
ItalicsTag,
HyperlinkTag
};
/// <summary>
/// See if the StackTag enum is a formatting-oriented enum (bold or italic).
/// This is an example of using switch with enum.
/// </summary>
/// <param name="tag">The enum to test.</param>
/// <returns>Whether the tag is a format tag.</returns>
public static bool IsFormatTag(StackTag tag)
{
// Use the enum in a switch to see if it is one of a subset
// of the available values. You could also check to see if it is valid.
switch (tag)
{
case StackTag.BoldTag:
case StackTag.ItalicsTag:
return true;
default:
return false;
}
}
Analysis tools like FxCop will complain if you don't provide a "None" value with 0 on each enum. This is because of the way .NET initializes member variables. It always initializes them to 0, so if there is no 0 on the enum, it will be an invalid value.
Use enums to improve code clarity and reduce the probability of invalid values. Use them to improve how you can display integers. Avoid "magic constants" or numbers with enums. They document themselves, and every developer following you will thank you for your wisdom.