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.
Note |
|---|
|
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).
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.
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 | |
For more information, see the following sections in the C# Language Specification:
-
1.10 Enums
-
6.2.2 Explicit Enumeration Conversions
-
14 Enums
for eg
enum days{sun, mon, tue,wed,thu,fri,sat};
here sun has value 0
n tue has 2 right?
so can i reverse this?
(int)days.tue
so dat i can display tue by giving d value 2???
Edit by SJ at MSFT: There is an example in this topic, http://msdn.microsoft.com/en-us/library/cc138362.aspx . Add the following loop to the Days example, and you will see how it works:
for (int i = 1; i <= 7; i++)
{
string s = Enum.GetName(typeof(Days), i);
Console.WriteLine(s);
}
- 3/17/2010
- Rocker19
- 11/2/2011
- SJ at MSFT
public static BookType
{
public const string HARDCOPY = "expensive";
public const string EBOOK = "cheap";
}
- 8/7/2008
- Leahn
- 4/30/2010
- SJ at MSFT
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;
- 7/23/2008
- salmanjamali
- 1/28/2010
- Informatosaurus
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.
- 10/1/2009
- I2055
- 1/16/2010
- Stanley Roark
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...
- 1/3/2010
- Erzengel des Lichtes
- 1/4/2010
- Erzengel des Lichtes
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.
- 7/9/2009
- Dave Conner
- 12/14/2009
- Brettly
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.
- 8/21/2009
- Cristian Chelaru
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.
- 4/3/2009
- Kozmoknot
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;
}
?
??
- 11/7/2007
- bav deLux
- 10/31/2008
- Stanley Roark
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#.
- 8/7/2008
- Leahn
- 7/17/2008
- Josh Rosenberg [MSFT]
- 2/12/2008
- Jonathan Conley
Note