Руководство C# Enum

1- Что такое C# Enum?

  Enum в C# является ключевым словом, которое используется для объявления перечисления (enumeration).
Теперь нам нужно увидеть, что нужно сделать если в некоторых ситуациях нет Enum. Например, вам нужен набор, содержащий дни недели. Обычно вы определяете 7 констант, представляющих 7 дней в неделю.
WeekDayConstants.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpEnumTutorial
{
    class WeekDayConstants
    {
         public const int MONDAY = 2;
         public const int TUESDAY = 3;
         public const int WEDNESDAY = 4;
         public const int THURSDAY = 5;

         public const int FRIDAY = 6;
         public const int SATURDAY = 7;
         public const int SUNDAY = 1;
    }

}
Класс с имитирующим методом получает задание соответствующее каждому конкретному дню недели. (Подобно расписанию).
Timetable.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpEnumTutorial
{
    
    class Timetable
    {
        // Returns name of Job will do
        public static String getJob(int dayInWeek)
        {
            if (dayInWeek == WeekDayConstants.SATURDAY
                    || dayInWeek == WeekDayConstants.SUNDAY)
            {
                return "Nothing";
            }
            return "Coding";
        }
    }

}
Очевидно, что такие кодовые строки не безопасны. Например, когда вы вводите значения дням недели и они совпадают. Или вызываете функцию Timetable.getJob(int), но входное значение не принадлежит определенным значениям.
  1. No Type-Safety (Не безопасный вид): Прежде всего, вы видите что ваш код не безопасен, вы можете вызвать метод GetJob(int) и передать любое значение.
  2. No Meaningful Printing (Нет значения печати): Если вы хотите напечатать дни недели, это будут числа, вместо словам со значением, как «ПОНЕДЕЛЬНИК»
А вот как использовать Enum для определения дней недели.
WeekDay.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpEnumTutorial
{
    public enum WeekDay
    {
       MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
    }

}
Вот пример использования enum​​​​​​​ Weekday ​​​​​:
Timetable2.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpEnumTutorial
{
    class Timetable2
    {
        public static String getJob(WeekDay weekDay)
        {
            if (weekDay == WeekDay.SATURDAY || weekDay == WeekDay.SUNDAY)
            {
                return "Nothing";
            }
            return "Coding";
        }
    }

}

2- Можно использовать оператор == для сравнения элементов enum

Enum - это reference object (ссылочный объект), такой как класс, интерфейс, но он также может использовать способ сравнения ==
Давайте посмотрим как сравниваются объекты сравнения (reference object):

// To compare the reference object, generally used method equals(..)
object obj1 = ...;

// Comparing object with null, can use the == operator
if (obj1 == null)
{

}

object obj2 = ...;
// Not null
if (obj1 != null)
{
    // Comparing two objects.
    if (obj1.Equals(obj2))
    {

    }
}
С Enum, вы можете использовать оператор == для сравнения.
CompareEnumDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpEnumTutorial
{
   class CompareEnumDemo
   {
       public static void Main(string[] args)
       {

           WeekDay today = WeekDay.SUNDAY;

           // Use the == operator to compare two elements of Enum
           if (today == WeekDay.SUNDAY)
           {
               Console.WriteLine("Today is Sunday");
           }
           Console.Read();
       }
   }

}

3- Выбраь на элементах Enum

Мы можем выбрать на всех элементах  Enum. См. примеры:
ValuesDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpEnumTutorial
{
    class ValuesDemo
    {
        public static void Main(string[] args)
        {
            

            // Get all the elements of the Enum.
            Array allDays = Enum.GetValues(typeof(WeekDay));

            foreach (WeekDay day in allDays)
            {
                Console.WriteLine("Day: " + day);
            }


            Console.Read();
        }       
           
    }

}
Результат запуска примера:

4- Enum и Attribute

Вы можете прикрепить attribute (атрибуты) к элементам Enum, что помогает Enum принести больше информации, и вы можете получить эту информацию в соответсвии с каждым элементом Enum.
Смотрите так же:
  • TODO Link!
GenderAttr.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpEnumTutorial
{
    class GenderAttr : Attribute
    {
        // code: M, text = Male
        // code: F, text = Female
        internal GenderAttr(string code, string text)
        {
            this.Code = code;
            this.Text = text;
        }

        public string Code { get; private set; }

        public string Text { get; private set; }  
             
    }

}
enum​​​​​​​  Gender (Пол) состоит из двух элементов: MALE (мужчины) и FEMALE (женщины).
Gender.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpEnumTutorial
{
    public enum Gender
    {
        // A element of Enum, has attribute
        [GenderAttr("M","Male")]
        MALE,

        // A element of Enum, has attribute
        [GenderAttr("F","Female")]
        FEMALE

    }

 
}
Genders.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;

namespace CSharpEnumTutorial
{
    class Genders
    {
        // Returns Gender corresponding to the code.
        // (This method may returns null)
        public static Gender? GetGenderByCode(string code)
        {
            // Get all the elements of the Enum.
            Array allGenders = Enum.GetValues(typeof(Gender));

            foreach (Gender gender in allGenders)
            {
                string c = GetCode(gender);
                if (c == code)
                {
                    return gender;
                }
            }
            return null;
        }

        public static string GetText(Gender gender)
        {
            GenderAttr genderAttr = GetAttr(gender);
            return genderAttr.Text;
        }

        public static string GetCode(Gender gender)
        {
            GenderAttr genderAttr = GetAttr(gender);
            return genderAttr.Code;
        }

        private static GenderAttr GetAttr(Gender gender)
        {
            MemberInfo memberInfo = GetMemberInfo(gender);
            return (GenderAttr)Attribute.GetCustomAttribute(memberInfo, typeof(GenderAttr));
        }

        private static MemberInfo GetMemberInfo(Gender gender)
        {
            MemberInfo memberInfo
                = typeof(Gender).GetField(Enum.GetName(typeof(Gender), gender));

            return memberInfo;
        }
    }

}
Пример использования enum  Gender ​​​​​:
GenderTest.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpEnumTutorial
{
   class GenderTest
   {
       public static void Main(string[] args)
       {

           Gender marryGender = Gender.FEMALE;

           Console.WriteLine("marryGender: " + marryGender);

           Console.WriteLine("Code: " + Genders.GetCode(marryGender)); // F
           Console.WriteLine("Text: " + Genders.GetText(marryGender)); // Femate


           
           String code = "M";
           Console.WriteLine("Code: " + code);

 
           // Phương thức có thể trả về null.
           Gender? gender = Genders.GetGenderByCode(code);

           Console.WriteLine("Gender by code: " + gender);

           Console.Read();
       }
   }

}
Запуск примера:

5- Может ли Enum иметь метод?

В C# enum не может иметь методы, но в случае, если вы хотите иметь что-то вроде Enum имеющий методы, вы можете определить class, этот class не позволяет создавать объекты дополнительно объекты, помимо тех которые доступны.
GenderX.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharpEnumTutorial
{
   class GenderX
   {
       
       public static readonly GenderX MALE = new GenderX("M","Male");

       public static readonly GenderX FEMALE = new GenderX("F","Female");

       private string code;
       private string text;

       // Private Constructor: Do not allow creating objects from outside class.
       private GenderX(string code, string text)
       {
           this.code = code;
           this.text = text;
       }

       public string GetCode()
       {
           return this.code;
       }

       public string GetText()
       {
           return this.text;
       }

       public static GenderX GetGenderByCode(string code)
       {
           if (MALE.code.Equals(code))
           {
               return MALE;
           }
           else if (FEMALE.code.Equals(code))
           {
               return FEMALE;
           }
           return null;
       }

   }


}