C# Language Reference
enum (C# Reference)

The enum keyword is used to declare an enumeration, a distinct type consisting of a set of named constants called the enumerator list. Every enumeration type has an underlying type, which can be any integral type except char. The default underlying type of the enumeration elements is int. By default, the first enumerator has the value 0, and the value of each successive enumerator is increased by 1. For example:

      enum Days {Sat, Sun, Mon, Tue, Wed, Thu, Fri};

In this enumeration, Sat is 0, Sun is 1, Mon is 2, and so forth. Enumerators can have initializers to override the default values. For example:

      enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};

In this enumeration, the sequence of elements is forced to start from 1 instead of 0.

A variable of type Days can be assigned any value in the range of the underlying type; the values are not limited to the named constants.

The default value of an enum E is the value produced by the expression (E)0.

NoteNote

An enumerator may not contain white space in its name.

The underlying type specifies how much storage is allocated for each enumerator. However, an explicit cast is needed to convert from enum type to an integral type. For example, the following statement assigns the enumerator Sun to a variable of the type int using a cast to convert from enum to int:

int x = (int)Days.Sun;

When you apply System.FlagsAttribute to an enumeration that contains some elements combined with a bitwise OR operation, you will notice that the attribute affects the behavior of the enum when used with some tools. You can notice these changes when using tools such as the Console class methods, the Expression Evaluator, and so forth. (See example 3).

Robust Programming

Assigning additional values new versions of enums, or changing the values of the enum members in a new version, can cause problems for dependant source code. It is often the case that enum values are used in switch statements, and if additional elements have been added to the enum type, the test for default values can return true unexpectedly.

If other developers will be using your code, it is important to provide guidelines on how their code should react if new elements are added to any enum types.

Example

In this example, an enumeration, Days, is declared. Two enumerators are explicitly converted to integer and assigned to integer variables.

// keyword_enum.cs
// enum initialization:
using System;
public class EnumTest 
{
    enum Days {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};

    static void Main() 
    {
        int x = (int)Days.Sun;
        int y = (int)Days.Fri;
        Console.WriteLine("Sun = {0}", x);
        Console.WriteLine("Fri = {0}", y);
    }
}

Output

Sun = 2
Fri = 7

In this example, the base-type option is used to declare an enum whose members are of the type long. Notice that even though the underlying type of the enumeration is long, the enumeration members must still be explicitly converted to type long using a cast.

// keyword_enum2.cs
// Using long enumerators
using System;
public class EnumTest 
{
    enum Range :long {Max = 2147483648L, Min = 255L};
    static void Main() 
    {
        long x = (long)Range.Max;
        long y = (long)Range.Min;
        Console.WriteLine("Max = {0}", x);
        Console.WriteLine("Min = {0}", y);
    }
}

Output

Max = 2147483648
Min = 255

The following code example illustrates the use and effect of the System.FlagsAttribute attribute on an enum declaration.

// enumFlags.cs
// Using the FlagsAttribute on enumerations.
using System;

[Flags]
public enum CarOptions
{
    SunRoof = 0x01,
    Spoiler = 0x02,
    FogLights = 0x04,
    TintedWindows = 0x08,
}

class FlagTest
{
    static void Main()
    {
        CarOptions options = CarOptions.SunRoof | CarOptions.FogLights;
        Console.WriteLine(options);
        Console.WriteLine((int)options);
    }
}

Output

SunRoof, FogLights
5
Comments

Notice that if you remove the initializer from Sat=1, the result will be:

Sun = 1
Fri = 6
Comments

Notice that if you remove FlagsAttribute, the example will output the following:

5

5

C# Language Specification

For more information, see the following sections in the C# Language Specification:

  • 1.10 Enums

  • 6.2.2 Explicit Enumeration Conversions

  • 14 Enums

See Also

Tasks

Attributes Sample

Reference

C# Keywords
Integral Types Table (C# Reference)
Built-In Types Table (C# Reference)
Implicit Numeric Conversions Table (C# Reference)
Explicit Numeric Conversions Table (C# Reference)

Concepts

C# Programming Guide
Enumeration Design

Other Resources

C# Reference

Tags :


Community Content

nbove
Implicit Conversion

Please allow implicit enum conversion in C#.  Forcing explicit conversion does not help code readability, in fact it does exactly the opposite.

Tags :

Stanley Roark
I'm with #1: an explicit cast is needed

what's the sense in:
switch((MyType)SomeInt)
{
case MyType.E0:
SomeOtherInt = (int)MyType.E1;
break;
}

wouldn't it be nicer this way:
switch(SomeInt)
{
case MyType.E0:
SomeOtherInt = MyType.E1;
break;
}
?


??

Tags :

Jonathan Conley
same as #1 and #2
enum is nothing more then a named int or whatever type you set it to having to cast it after that makes no sense.
Tags :

Josh Rosenberg [MSFT]
Disagreement with all of the above
enums should not do implicit conversion (at least, not by default), because then their primary raison d'etre is eliminated. enums were created to enable easy compiler-time checks to ensure only accepted values were provided to a function or other construct, and to enable the use of names in cases where numerics don't matter. If they convert seamlessly to and from the underlying type, then you may as well use just declare int constants and be done with it, because you'll be back where we started, and enums will just be a short hand for a list of constants.
Tags :

Informatosaurus
I was wondering

I was wondering if enums in C# could possibly be used to do the following:

BookType {
HARDCOPY = "expensive",
EBOOK = "cheap"
}

String bookTypePriceIdea = (String) BookType.HARDCOPY;


Leahn
To ShadowRanger
ShadowRanger, enum, as per the documentation, are substituted for their respecitve numeric value during compiler time, which means that your program knows no enum, only its values, so yes, implicit conversion makes sense. It is already a constant of type int (or whatever type your assigned to it) so casting it should not be needed.

Also, enum in C#, unlike their counterparts in other languages DO NOT enforce the accepted values, if you declare an enum with values ranging from 1 to 7, and I pass a "(<enumName>)10 " to your function as a parameter, it will be accepted. C/C++ overlap the values, so if I passed 10, the compiler would switch it to 3 during compiling time. C# does not do this.

To finish, enums are ONLY int constants, the purpose of their name is simply to make it easier for you to remember the correct value to pass (easier to remember 'ReturnValue.Success' than '5'). Any other language with much tigher enum specification allow free conversion from the enum to its underlying type. C/C++ even allow you do to aritmetic operations straight with the enum values (and overlap the result accordingly). VB.NET allows free conversion to the underlying type. There is no reason to not to allow it as well in C#.


Tags :

pbnec
To salmanjamali
You can attain what you want with the following syntax:

public static BookType

{

public const string HARDCOPY = "expensive";

public const string EBOOK = "cheap";

}


Tags : contentbug

Kozmoknot
For Leahn and possilby the other questions
Your code doesn't work...it needs the "struct" value type specified instead of "static":

public struct BookType

{

public const string HARDCOPY = "expensive";

public const string EBOOK = "cheap";

}


A struct may also be used instead of an enum to accomplish implicit conversions to an integral type.
Tags :

Brettly
Quick Note to Salmanjamli, Leahn and Kozmoknot

Perhaps Leahn simply left out the keyword class in her code.

public static class BookType
{
public const string HARDCOPY = "expensive";
public const string EBOOK = "cheap";
public const string kindle = "other";
}
certainly would work.

However I agree with Kozmoknot - if this is the extent of the members there is no reason to use a class. One would be better off using a struct. In the CLR, a struct is a value type, is lighter weight and allocated directly from the stack.

**Don't use a struct here, use a class. In the case where we are using strings we would create a class (reference type) because strings are character arrays which are reference types.

We only use structs where:
- the total size of the instance will be 16 bytes or less
- the struct logically represents a single value
- we will not cast the struct to a reference type

We use structs for better performance however structs only suit simple values otherwise structs are inefficient.


Cristian Chelaru
Extendable enums
I nice feature, and not too hard to implement (at least in C#, since Enum is actually a class), would be enum extendability. More than once had I wished for some enum values available in one enum to be present in another one, along with others - custom defined. Some very relevant examples would be:

1. Creating customized message boxes, with customized DialogResult, MessageBoxButtons and MessageBoxIcon. It would have been much simpler and elegant, had this feature been implemented.
2. Creating customized exceptions, and defining an ErrorCode property, which - if defined as an enum type - would allow extended exceptions to use the same error codes, and also add their own, very elegant and easy.

etki
MS failed on enums

why did MS mess up such a a basic concept introduced in the early 80's... maybe even earlier...?

i can't imagine any more common uses than switch statements and as indexes into arrays and vector types.

so, why the (int) type casting?

if, MS was really smart, they would have just copied Ada's implementation ... i.e. 'Pos, 'Val, 'First, 'Last, etc

why reinvent a bad wheel... a square one.


Stanley Roark
Magical "0" value for enums
Try this one on for size. You can pass a zero as an enum even if there is no 0 defined (.net 2.0). If you change the 0 to anything else, even a defined integer in the enum, the program will no longer compile. Just what is the thinking here with the magical 0? FAIL

namespace Fail
{
class Program
{
static void Main(string[] args)
{
var f = new Fail(0);
}
}

public class Fail
{
private SomeEnum mEnu;
public Fail(SomeEnum enu)
{
mEnu = enu;
}
}

public enum SomeEnum
{
Critical = 1,
Important = 2,
Warning = 3,
Information = 4
}
}

---
By default, the first enumerator has the value 0, and the value of each successive enumerator is increased by 1. The default value of an enum E is the value produced by the expression (E)0, which in your example (SomeEnum)0 = 0. 0 can be thought of as SomeEnum.Default and is always present whether you declared it or not. This would become a logical error, although the code Fail(0) should never be written as this violates exactly what you are trying to avoid by using an enum and should be Fail(SomeEnum.SomeValue). While not magical, the behavior is indeed odd and it is good that you have pointed this out.
Tags :

Erzengel des Lichtes
Using enums "implicitely" for arrays
If you're willing to create your own arrays/lists/whatever, you can do the following:
public T this[Enum index]
{
return std_array[((IConvertible)index).ToInt32(null)];
}

Then simply using Variable[Enum.Value]; will work. Since it uses Enum as the type, any enum will work. If one used IConvertible itself instead, anything that implements IConvertible would work, including (for example) floats, which would not be desirable.

Personally I use:
static class ExtendingList
{
public static T i<T>(this IList<T> This, Enum index)
{
return This[((IConvertible)index).ToInt32(null)];
}
public static void i<T>(this IList<T> This, Enum index, T to)
{
This[((IConvertible)index).ToInt32(null)] = to;
}

}
then I can use std_array.i(Enum.Value); It's, unfortunately, less readable, but until there's a way to extend indexers...
Tags :

hazyhxj
The brain of the designer must be made of bull ***
God damn this explicit conversion
Tags :

Page view tracker