[C#] 從列舉中取得自訂Attribute

摘要:[C#] 從列舉中取得自訂Attribute

最近在寫case時遇到需要對某些特定字串進行處理,想到可以利用列舉+Attribute 來Mapping 對應的文字。好處是如果字串需要修改的時候,不用修改關係到的程式,只要修改列舉上面的Attribute,比較好維護,再來就是列舉就是強型別,不怕打錯字XD....那就開始著手吧㊣

Attribute

 [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
    public sealed class StatisticsFeedAttribute:Attribute
    {
        public string Field { get; set; }
        public StatisticsFeedAttribute()
        {
         
        }
    }

Enum

	public enum StatisticType
	{
	[StatisticsFeed(Field = "top_rated")]
	TopRated,
	[StatisticsFeed(Field = "top_favorites")]
	TopFavorites,
	[StatisticsFeed(Field = "most_viewed")]
	Viewed,
	[StatisticsFeed(Field = "most_shared")]
	Shared,	
        }

再來就是寫個擴充方法來取得列舉值的Attribute

public static T GetAttribute(this Enum e) where T : Attribute, new()
        {
            FieldInfo[] Fields = e.GetType().GetFields();
            foreach (FieldInfo item in Fields)
            {

                T t = (T)Attribute.GetCustomAttribute(item, typeof(T));
                if (t != null)
                {
                    if (item.Name == e.ToString())
                        return (T)t;
                }
            }
            return null;
        }

這樣看起是可以使用,但在使用時發現以下錯誤

在建構Attribute時我們不一定是使用無參數建構函式,有時也是有需要只有參數建構函式的時候,所以再寫一個擴充方法來滿足這種情況

public static Attribute GetAttribute(this Enum e, Type typeAttribute)
        {
            FieldInfo[] Fields = e.GetType().GetFields();
            foreach (FieldInfo item in Fields)
            {
                Attribute t = Attribute.GetCustomAttribute(item, typeAttribute);
                if (t != null)
                {
                    if (item.Name == e.ToString())
                        return t;
                }
            }
            return null;
        }

有個小缺點,就是還要自已轉成自訂的Attrbiute就是了。

以上這兩種方法都有一個限制就是Attribute 有設定AllowMultiple = false ,就是一個列舉值不能有多個相同的Attribute。