C# Enum

Array Collections File Keyword String .NET Cast Class Compression Data Directive Enum Exception If Interface Lambda LINQ Loop Method Number Process Property Regex Sort StringBuilder Struct Switch Time Windows WPF

Enum

Enums store special values. They make programs simpler. If you place constants directly where used, your program becomes complex. It becomes hard to change. With an enum, these magic constants are separate.

Example

Here we see an enum type that indicates the importance of something. An enum type internally contains an enumerator list. We use enums when we want readable code that uses constants.

Important

Tip:The underlying value of this enum is the default, which is int. When you use an Importance variable, it is actually an int.

Syntax:An enum is a form of syntactic sugar. It makes programs cleaner and easier to read. It also causes no slowdown at runtime.

Based on:

.NET 4.5

Program that uses enums: C#

using System;

class Program
{
    enum Importance
    {
	None,
	Trivial,
	Regular,
	Important,
	Critical
    };

    static void Main()
    {
	// ... An enum local variable.
	Importance value = Importance.Critical;

	// ... Test against known Importance values.
	if (value == Importance.Trivial)
	{
	    Console.WriteLine("Not true");
	}
	else if (value == Importance.Critical)
	{
	    Console.WriteLine("True");
	}
    }
}

Output

True
Piece of computer software: a program

A new variable with the identifier "value" is of the Importance type. It is initialized to Importance.Critical in the first statement. Then, the variable is tested with an if-statement against other enum constants.

If

Tip:Enums can be used IntelliSense in Visual Studio. This feature will guess the value you are typing.

So:You can simply press tab and select the enum type you want. This is an advantage to using enum types.

Debugger

Next, we examine what enums look like in the Visual Studio debugger. We see that enums are strongly-typed. You cannot assign them to just any value. The code example below is what we see in the debugger.

Enum locals, Visual Studio debugger

Note:The debugger shows that en1 and en2 are of type Program.E. But internally, these two variables are stored as integers.

Program 2: C#

using System;

class Program
{
    enum E
    {
	None,
	BoldTag,
	ItalicsTag,
	HyperlinkTag,
    };

    static void Main()
    {
	// ... These values are enum E types.
	E en1 = E.BoldTag;
	E en2 = E.ItalicsTag;

	if (en1 == E.BoldTag)
	{
	    // Will be printed.
	    Console.WriteLine("Bold");
	}
	if (en1 == E.HyperlinkTag)
	{
	    // Won't be printed.
	    Console.WriteLine("Not true");
	}
    }
}

Output

Bold

Strings

Console screenshot

We convert enums to strings for display on the Console.
Enum values always have a name,
such as E.None,
E.BoldTag
or E.ItalicsTag. These are custom. You can specify any names you want.

Tip:To print out the enum values, you can call ToString on the enum variable in a program.

Also:Another method such as Console.WriteLine can automatically call the ToString method.

Program that writes enums: C#

using System;

class Program
{
    static void Main()
    {
	// ... Two enum variables.
	B b1 = B.Dog;
	V v1 = V.Hidden;

	// ... Print out their values.
	Console.WriteLine(b1);
	Console.WriteLine(v1);
    }

    enum V
    {
	None,
	Hidden = 2,
	Visible = 4
    };

    enum B
    {
	None,
	Cat = 1,
	Dog = 2
    };
}

Output

Dog
Hidden
String type

Console will call the ToString method on all types passed to it. This is how the string representation of the enum is found. Internally, ToString invokes methods that use reflection to acquire the string representation.

Enum ToString

Note:Many of the example programs on this page use short, letter-based identifiers (b1, v2) for enum variables.

But:There are not ideal. It would be better to use more descriptive words, such as "animal" or "visibility."

Convert

Convert

Sometimes you have a string value that you want to convert to an equivalent enum. This could happen when you are accepting user input and want to put the data into your objects. The language provides a way to convert strings to enums.

Tip:When using the .NET Framework, calling a built-in method to do conversions (where one exists) is usually best.

Typeof operator

Enum.Parse:The tricky part of using this method involves typeof and casting. It is best to avoid this if possible.

Enum.ParseTypeof Operator

Get names. It is possible to get the name for any value of a specified enum. You can also get all the string representations of the enum values at once. This is done with the GetNames method. This streamlines code.

Enum.GetNameFormat

Format enums. It is possible to format the values stored in enums in different ways. You can display an integer representation, or a hex representation. This is useful in certain programs.

Enum.Format

Switch

Switch

The above samples show the if-statement used with enums. However, switch in the C# language is sometimes compiled to more efficient IL. Here we want to use switch on an enum variable.

Switch Enum

Here:In this example, the IsFormat method works as a filter that tells us something about sets of enum values.

Tip:We can separate the logic here instead of repeating ourselves. This helps clarify the program logic.

Program that uses switch enums: C#

using System;

class Program
{
    static void Main()
    {
	// ... Test enum with switch method.
	G e1 = G.None;
	if (IsFormat(e1))
	{
	    // Won't succeed.
	    // ... G.None is not a format value.
	    Console.WriteLine("Error");
	}

	// ... Test another enum with switch.
	G e2 = G.ItalicsFormat;
	if (IsFormat(e2))
	{
	    // Will succeed.
	    // ... G.ItalicsFormat is a format value.
	    Console.WriteLine("True");
	}
    }

    enum G
    {
	None,
	BoldFormat,    // Is a format value.
	ItalicsFormat, // Is a format value.
	Hyperlink      // Not a format value.
    };

    /// <summary>
    /// Returns true if the G enum value is a format value.
    /// </summary>
    public static bool IsFormat(G e)
    {
	switch (e)
	{
	    case G.BoldFormat:
	    case G.ItalicsFormat:
		{
		    // These two values are format values.
		    return true;
		}
	    default:
		{
		    // The argument is not a format value.
		    return false;
		}
	}
    }
}

Output

True

Default

Default operator

Values are always initialized to zero when they are fields of a class. An enum field will also be initialized to zero. To make enums valid, always use the default value of zero. This way, you can test for the default value of fields.

Sometimes:This issue is not worth fixing.
But it is often useful for verifying correctness.

Enum with default value of None: C#

enum E
{
    None,
    A,
    B,
    C
};
FxCop

Microsoft's FxCop analysis tool will tell you that "enums should have zero value." You should "define a member with the value of zero so that the default value is a valid value of the enumeration. If appropriate, name the member None."

Enums should have zero value: MSDN

Collections

Framework: NET

Next, we look at how you can use enumerated types with data structures. Here we use the Stack collection in the .NET Framework. With Stack, we can develop a parser that keeps the most recently encountered enum value on the top.

Result:In the execution of this program, the stack has two enums added and one removed.

Program that uses Stack with enums: C#

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
	M();
    }

    enum E
    {
	None,         // integer value = 0
	BoldTag,      // 1
	ItalicsTag,   // 2
	HyperlinkTag, // 3
    };

    static public void M()
    {
	// ... Stack of enums.
	Stack<E> stack = new Stack<E>();

	// ... Add enum values to the Stack.
	stack.Push(E.BoldTag); // Add bold
	stack.Push(E.ItalicsTag); // Add italics

	// ... Get the top enum value.
	E thisTag = stack.Pop(); // Get top tag.
	Console.WriteLine(thisTag);
    }
}

Output

ItalicsTag
Mathematical constant e: Euler's number

It uses an enum E. The name E here is custom and can be anything. The enum keyword is important. We do not assign any specific numbers to the enum values. When you don't provide numbers, they start at zero and are incremented.

Stack:In part A, the Stack here can only have E values added to it. This enables type checking and validation.

Then:With the Pop method we get the top element from the stack.
This is of type E.ItalicsTag.

Stack

Type

Byte type

An enum has an underlying type. Each time you use the enum, you are actually using the underlying type with syntactic sugar on top. Enums are by default an int type, but we can adjust this to a different numeric type.

Byte:Here we create an enum with a type of byte.
This is sometimes useful on small enums.
A byte can only contain 256 different values.

Memory:The CoffeeSize enum will use memory equivalent to a byte. This can make classes more efficient and smaller.

Program that uses underlying type: C#

using System;

class Program
{
    enum CoffeeSize : byte
    {
	None,
	Tall,
	Venti,
	Grande
    };

    static void Main()
    {
	// ... Create a coffee size local.
	CoffeeSize size = CoffeeSize.Venti;
	Console.WriteLine(size);
    }
}

Output

Venti

Flags

Attribute Flags syntax

The language also allows you to specify a special Flags attribute on an enum. This enables the enum to be used as a bitfield. You can use combinations of enum values this way. But there are limitations.

Flags

Arrays

Array

Enums are values. This means you can use enums as keys to arrays by converting them to integers. This approach can be useful for some kinds of tables or data structures in your programs.

Enum Array Example

Internals

Value

Each enum has an underlying type. This is a value type that is where the actual data is stored. The GetUnderlyingType method on the Enum type provides a way to programmatically access this type.

GetUnderlyingType

Performance:Will enums impact the performance of your C# programs? We look at the intermediate language of enum types to determine this.

Enum Performance

Memory. Let us consider memory usage of enums. Suppose you develop a class that uses a field that is an enum type. The underlying type of this enum contributes to how much memory your class will use.

So:Using a smaller type, such as byte, can make programs that create many instances of your class more efficient.

Summary

C# programming language

Enums improve code clarity and reduce the probability of invalid constants. We use them to represent constant values such as integers in a consistent way. Enums are checked by the compiler.

Thus:It is a good idea to avoid magic constants and numbers. Instead, prefer a self-documenting enum type.

C#