Enum Extension

  • 1490
  • 0
  • C#
  • 2019-05-12

在Enum上除了可以設定 description 這個attribute外,也許還會想要放更多客製化的attribute,這時就該來寫個擴充方法方便一下

Enum的好用不在話下,但也許你會在上面設定一些 attribute

假設我們有一個SoundsEnum,我們會為這個enum設置color, size 這一類的description

        [AnimalColorAttribute("Tiger Color")]
        [AnimalSize("Small")]
        [Description("Cat")]
        Miao = 2,
        [AnimalColorAttribute("Black Color")]
        [AnimalSize("Middle")]
        [Description("Dog")]
        Wong = 3

我們也許會做這樣的事情

1. 根據Miao 這個enum 來抓AnimalColorAttribute , AnimalSize...的資料

2.我們有Black Color這個description,想對應回去AnimalColorAttribute後得到是哪種聲音

這時候不如就寫個enum的擴充工具吧

1. 首先我們先建立AnimalColorAttribute , AnimalSize這兩個attribute吧,記得要繼承Attribute class

在overwrite toString這邊,我們回傳了相對應attribute一開始初始化的description

 public class AnimalColorAttribute : Attribute
    {
        public string Description { get; set; }

        public AnimalColorAttribute(string Description)
        {
            this.Description = Description;
        }

        public override string ToString()
        {
            return this.Description;
        }

    }

2. 接著來寫從enum中抓取特定的attribute吧,這時候我們抓到attribute後怎麼得到 description呢

還記得我們上面建立attribute有overwrite掉toString的function嗎,直接呼叫就可以了

        public static T GetAttributeFromEnum<T>(this System.Enum enumVal) where T : System.Attribute
        {
            var type = enumVal.GetType();
            var memInfo = type.GetMember(enumVal.ToString());
            var attributes = memInfo[0].GetCustomAttributes(typeof(T), false);
            return (attributes.Length > 0) ? (T)attributes[0] : null;
        }

 

3. 接著我們再來寫根據description是什麼,再根據attribute 填入的值來找出是哪一個enum

A為希望找尋的attribute欄位,E則為要回傳的enum,再來就是要找尋attribute的description是什麼

這一段主要是從填入的enum 裡去找尋所有的列舉 cat or dog,再針對我們填入的attribute去抓

如果有的話再去比對description是不是一致,如果一致,就回傳相對應的

但原本的description attribute .toString()並不會回傳description,得透過公開存取的方式去抓description

若是我們客製化的attribute 有overwrite toString() 即可抓到description,所以這邊會分兩種狀況處理

      public static E GetValueFromCustomDescription<A, E>(this string description) 
          where A : System.Attribute
          where E:  IComparable, IFormattable, IConvertible //enum
        {
            var type = typeof(E);
            string attribute_description = string.Empty;
            foreach (var field in type.GetFields())
            {
                var attribute = Attribute.GetCustomAttribute(field,
                    typeof(A)) as A;
                if (attribute != null)
                {
                    if (typeof(A) == typeof(DescriptionAttribute))
                        attribute_description = (attribute as DescriptionAttribute).Description;
                    else
                        //需確定客製化的attribute是否有overwite tostring
                        attribute_description = attribute.ToString();

                    if (attribute_description == description)
                        return field.GetValue(null).GetJsonString().JsonConvertToModel<E>();
                }
                else
                {
                    if (field.Name == description)
                        return field.GetValue(null).GetJsonString().JsonConvertToModel<E>();
                }
            }
            throw new ArgumentException("Not found.", "description");
            // or return default(T);
        }

 

測試

            SoundsEnum animal_miao = SoundsEnum.Miao;
            SoundsEnum animal_wong = SoundsEnum.Wong;

            //get description
            string desc_animal_miao = Utility.EnumExt.GetAttributeFromEnum<DescriptionAttribute>(animal_miao).Description;
            string desc_animal_wong = Utility.EnumExt.GetAttributeFromEnum<DescriptionAttribute>(animal_wong).Description; ;
            Console.WriteLine(desc_animal_miao);
            Console.WriteLine(desc_animal_wong);

            //get color description
            string customColorDesc_animal_miao = Utility.EnumExt.GetAttributeFromEnum<AnimalColorAttribute>(animal_miao).ToString();
            string customColorDesc_animal_wong = Utility.EnumExt.GetAttributeFromEnum<AnimalColorAttribute>(animal_wong).ToString();
            Console.WriteLine(customColorDesc_animal_miao);
            Console.WriteLine(customColorDesc_animal_wong);


            //get size
            string customSizeDesc_animal_miao = Utility.EnumExt.GetAttributeFromEnum<AnimalSizeAttribute>(animal_miao).ToString();
            string customSizeDesc_animal_wong = Utility.EnumExt.GetAttributeFromEnum<AnimalSizeAttribute>(animal_wong).ToString();
            Console.WriteLine(customSizeDesc_animal_miao);
            Console.WriteLine(customSizeDesc_animal_wong);

            //get value
            Console.WriteLine((int)Utility.EnumExt.GetValueFromCustomDescription<AnimalSizeAttribute, SoundsEnum>(customSizeDesc_animal_miao));
            Console.WriteLine((int)Utility.EnumExt.GetValueFromCustomDescription<AnimalSizeAttribute, SoundsEnum>(customSizeDesc_animal_wong));
            Console.WriteLine((int)Utility.EnumExt.GetValueFromCustomDescription<DescriptionAttribute, SoundsEnum>("Cat"));

 

git hub 原始碼請參考

https://github.com/daship/EnumSample