You must have heard of various keywords of C# like int, string etc, Enum is little bit different keyword which is used to create set of named constants, so you can say an enumerated type is declared using the enum keyword.

C# enumerations contains it's own value and cannot inherit or cannot pass inheritance.Enums can be of any type, but usually it an integer (float, int, byte, double etc.), but if you used beside int it has to be cast.

Declaring Enums

The general syntax for declaring an enumeration is -

enum <enum_name> {
   your enumeration list 
};

enum_name= name of your enumeration type  &  enumeration list is comma-separated list of identifiers.

By default, the first enumerator has the value 0, and the value of each successive enumerator is increased by 1. For Example, you are creating an attendance log application in which a variable can contains value from Monday to Friday only. The other value will not be applicable with variables. In order to fulfill this requirement you need to use enumeration that will hold only assigned values and will returns numeric position of values starting with zero.

So your C# code for it will be

public enum attandance
    {
        Monday,
        Tuesday,
        Wednesday,
        Thursday,
        Friday
    }

Considering above enumeration list, Monday=0, Tuesday=1, Wedenesday=2, Thursday=3, Friday=4

Let's create a complete C# code and execute it to understand it more clearly.

using System;

namespace EnumApp {
   class EnumProgram {
      enum attendance { Mon, tue, Wed, thu, Fri };

      static void Main(string[] args) {
         int WeekdayStart = (int)attendance.Mon;
         int WeekdayEnd = (int)attendance.Fri;
         
         Console.WriteLine("Monday: {0}", WeekdayStart);
         Console.WriteLine("Friday: {0}", WeekdayEnd);
         Console.ReadKey();
      }
   }
}

Output of the above code will be

Monday: 1
Friday: 5

You can execute it online here and check it's output https://paiza.io/projects/E1JIDobNYT5DkPtp30p0rQ?language=csharp

Advantages of using Enums

  1. Enumeration provides efficient way to assign multiple constant integral values to a single variable. 
  2. Enumeration improves code clarity and makes program easier to maintain
  3. Reduces errors caused by transposing or mistyping numbers.
  4. Ensures forward compatibility as it is easy to change constants without affecting throughout the project.
  5. Easy maintenance.

Basic real world usage

Take for example this very simple Employee class with a constructor:

You could do it like this(Without Enums)

public class Employee
{
    private string _sex;

    public Employee(string sex)
    {
       _sex = sex;
    }
}

Now, when using it in your C# code to declare and use it, you would have to code like this

Employee employee = new Employee("Male");

Now using Enums, you can have code like this

public enum Sex
{
    Male = 10,
    Female = 20
}

public class Employee
{
    private Sex _sex;

    public Employee(Sex sex)
    {
       _sex = sex;
    }
} 

So, consumer of the  Employee class to use it much more easily now

Employee employee = new Employee(Sex.Male);

so it improves code readability and makes it easier to customize in future( if needed).Source

Iterate through an enumeration (enums) in C#

Suppose you have the following enum declared

public enum Suits
{
    Spades,
    Hearts,
    Clubs,
    Diamonds,
    NumSuits
}

then you can iterate through enumeration using Enum.GetValues(typeof(Enum_Name))

public void PrintAllSuits()
{
    foreach (var suit in Enum.GetValues(typeof(Suits)))
    {
        System.Console.WriteLine(suit.ToString());
    }
}

complete C# code for the above example

using System;

namespace EnumApp {
   class EnumProgram {
      public enum Suits
        {
            Spades,
            Hearts,
            Clubs,
            Diamonds,
            NumSuits
        }

      static void Main(string[] args) {
         foreach (var suit in Enum.GetValues(typeof(Suits)))
            {
                System.Console.WriteLine(suit.ToString());
            }
         Console.ReadKey();
      }
   }
}

Here is the Output image

enum-example-in-c-sharp-min

Here is the working link for the above example https://paiza.io/projects/atwCBIo_I32V1uW0Imo9qA?language=csharp

On the other hand,  When  we use GetValues(),   Actually, GetValues() will return an int array containing 0,1,2,3,4 . You can easily type cast the values, and make it work like below

   foreach (var suit in Enum.GetValues(typeof(Suits)))
            {
                System.Console.WriteLine(Convert.ToInt32(suit));
            }

Output of the above code will be

0
1
2
3
4

So complete code for the above output will be

using System;

namespace EnumApp {
   class EnumProgram {
      public enum Suits
        {
            Spades,
            Hearts,
            Clubs,
            Diamonds,
            NumSuits
        }

      static void Main(string[] args) {
         foreach (var suit in Enum.GetValues(typeof(Suits)))
            {
                System.Console.WriteLine(Convert.ToInt32(suit));
            }
         Console.ReadKey();
      }
   }
}

Flag Attribute in Enums

Flags attribute should be used when ever the enumerable represents a collection of values, rather than a single value.

Flags attribute example:

 
class Program
    {
        [Flags]
        public enum EPropertyTypes
        {
            Flats = 1,
            Villas = 2,
            Duplexus = 4,
            Office = 6,
            Shop = 8,
            Condos = 10
        }

        static void Main(string[] args)
        {

            EPropertyTypes allowedTypes = EPropertyTypes.Flats | EPropertyTypes.Shop;

            Console.WriteLine(allowedTypes);
            Console.WriteLine((int)allowedTypes);

            if ((allowedTypes & EPropertyTypes.Flats) == EPropertyTypes.Flats)
            {
                Console.WriteLine("Property Type is Flats");
            }

            if ((allowedTypes & EPropertyTypes.Condos) == EPropertyTypes.Condos)
            {
                Console.WriteLine("Property Type is Condos");
            }


        }
    }

Output:

Flats, Shop
9

When [Flags] attribute with enum is sued then members of an enum should have power of 2 means you need to multiply the last value with 2. So same technique we have applied in our above example we have multiplied the last value of enum member i.e. Flats = 1 with 2 and rest member in series.

Few points about enums

  1. enums are strongly typed constant. They are strongly typed, i.e. an enum of one type may not be implicitly assigned to an enum of another type even though the underlying value of their members are the same.
  2. enum values are fixed. enum can be displayed as a string and processed as an integer.
  3. The default enumeration type is int, and other approved types are sbyte, byte, ushort, short, long, uint, and ulong.
  4. Flags Enumeration provides us to assign the multiple values to an enum member or an enum object.