在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 原始碼請參考