C# enum

The enum keyword is used to declare an enumeration type which consists of a batch of constants. Defining an enum type makes the program readable and clear without losing any performance because the value of the enumeration is converted to its underlying integral value at compile time.

Syntax to define a enum type:

enum <TypeName> [: <Integal Type>] { <Constant 1> [= <value 1>], <Constant 2> [= <value 2>], ..., <Constant n> [= <value n>] }
  • An enum type can be defined in a namespace so that it can be shared in the whole namespace and it can also be defined in an individual class or struct.
  • Each enumeration type has an underlying type, by default the underlying type is int and it can be defined to other integral types such as byte, sbyte, short, ushort, uint, long, or ulong.
  • By default, the underlying value of the first constant in enum is 0 and thereafter values are defined as the previous value plus 1.
  • The underlying values can be changed by assigning a value or a computing expression explicitly when declaring the enumeration type.
  • A variable of an enumeration type can be declared as usual and it can be assigned any value of the underlying type.
  • The default value of an enumeration type is (E)0 if the enumeration name is E.
  • No matter whether a conversion is from an enum type to an integral type or from an integral type to an enum type, a explicit cast is needed.

Example 01-92-01

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
using System;

public class Program
{
    enum Month : byte { Jan = 1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec };
    enum EvenDigit { Zero, Two = 2, Four = 4, Six = Four + 2, Eight = Six + 2 };
    enum Number { A, B , C = 5, D, E = -1, F, G };
    enum Color { Red = 1, Blue = 1 };

    static void Main()
    {
        testMonth();
        testEvenDigit();
        testNumber();
        testColor();

        Console.Read();
    }

    static void testMonth()
    {
        Month m = Month.May;
        byte b = (byte)m;
        Console.WriteLine("m={0}, b={1}", m, b);

        Month[] mm = new Month[2];
        Console.WriteLine("mm[0]={0}, mm[1]={1}", mm[0], mm[1]);
    }

    static void testEvenDigit()
    {
        EvenDigit[] d = new EvenDigit[1];
        Console.WriteLine("d[0]={0}", d[0]);

        for (int i = 0; i < 10; i++)
        {
            Console.Write("{0}, ", (EvenDigit)i);
        }
        Console.WriteLine();
    }

    static void testNumber()
    {
        Number x = Number.A;
        Console.WriteLine("x={0}", x);
        Console.WriteLine("x={0}", (Number)0);

        for (int i = -1; i < 7; i++)
        {
            Console.Write("{0}, ", (Number)i);
        }
        Console.WriteLine();
    }

    static void testColor()
    {
        Color c = (Color)1;
        Console.WriteLine("c={0}", c);
        Console.WriteLine("c={0}", Color.Blue);
    }
}

Output

m=May, b=5
mm[0]=0, mm[1]=0
d[0]=Zero
Zero, 1, Two, 3, Four, 5, Six, 7, Eight, 9, 
x=F
x=F
E, F, G, 2, 3, 4, C, D, 
c=Red
c=Red

Explanation

  • Line 5: Declare an enum Month with underlying type byte and starting with 1.
  • Line 6: Declare an enum EvenDigit with default int type. Six and Eight are defined with computing expressions instead of values.
  • Line 7: It is equivalent to { A = 0, B = 1 , C = 5, D = 6, E = -1, F = 0, G = 1 }.
  • Line 8: Declare an enum Color and the two constants have the same value.
  • Line 12-15: Test the 4 enums.
  • Line 22: Declare a variable of Month type with initialized value Month.May.
  • Line 23: Explicit cast the variable m to a byte and the result is 5.
  • Line 26-27: Test the default value of Month type and they are 0 but there is no named constant hold the value 0 so it is printed with 0 directly.
  • Line 32-33: Test the default value of EvenDigit and this time the default value is Zero because the underlying value of zero is 0.
  • Line 35-38: Output EvenDigit typed constants which underlying values are from 0 to 9.
  • Line 44-46: This is interesting. Both A and F have the same value 0 and F is printed eventually.
  • Line 48-51: A and B have no opportunity to be printed because A's value is the same as F's and B's value is the same as G's.
  • Line 57-59: One more testing on constants with the same value. This time the first constant Red is printed. So declaring the constants with the same value in an enum type doesn't make any sense and the output constant seems picked up randomly.

DayOfWeek Enumeration is a pre-defined enum type in C# and you can check it here for details. It was defined somewhere like below.

public enum DayOfWeek { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };

In the following example, firstly we'll print out each value of the named constants defined in DayOfWeek and then we'll calculate how many weekends and weekdays in 2015.

Example 01-92-02

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
using System;

public class Program
{
    static void outDayOfWeek()
    {
        for (int i = 0; i < 7; i++)
        {
            Console.WriteLine("{0} : {1}", i, (DayOfWeek)i);
        }
    }

    static void outTotals(int thisYear)
    {
        if (thisYear < 1 || thisYear > 9999) return;

        DateTime dt = new DateTime(thisYear, 1, 1);
        DateTime lastDay = new DateTime(thisYear, 12, 31, 23, 59, 59);
        int totalWeekends = 0, totalWeekdays = 0;

        while (dt < lastDay)
        {
            switch (dt.DayOfWeek)
            {
                case DayOfWeek.Sunday:
                case DayOfWeek.Saturday:
                    totalWeekends++;
                    break;
                case DayOfWeek.Monday:
                case DayOfWeek.Tuesday:
                case DayOfWeek.Wednesday:
                case DayOfWeek.Thursday:
                case DayOfWeek.Friday:
                    totalWeekdays++;
                    break;
            }
            dt = dt.AddDays(1);
        }

        Console.WriteLine("Total Weekends: {0}", totalWeekends);
        Console.WriteLine("Total Weekdays: {0}", totalWeekdays);
    }

    static void Main()
    {
        outDayOfWeek();
        outTotals(2015);

        Console.Read();
    }
}

Output

0 : Sunday
1 : Monday
2 : Tuesday
3 : Wednesday
4 : Thursday
5 : Friday
6 : Saturday
Total Weekends: 104
Total Weekdays: 261

Explanation

  • Line 7-10: Output the named constants of DayOfWeek and their values.
  • Line 15: Return if the year is out of the year range of a DateTime type.
  • Line 21: Process from Jan 1 to the Dec 31 of the year.
  • Line 23: A switch statement is used to check the DayOfWeek of dt. DayOfWeek is a property of C# DateTime class.
  • Line 25-28: If it is a Saturday or Sunday, we'll add 1 to totalWeekends.
  • Line 29-35: If it is a weekday, we'll add 1 to totalWeekdays.
  • Line 37: Assign the next day to dt to continue the processing.