2011-02-23 142 views
28

我有一個枚舉,其中每個成員都有一個自定義屬性應用於它。我如何檢索存儲在每個屬性中的值?如何獲取枚舉的自定義屬性值?

現在我這樣做:

var attributes = typeof (EffectType).GetCustomAttributes (false); 
foreach (object attribute in attributes) 
{ 
    GPUShaderAttribute attr = (GPUShaderAttribute) attribute; 
    if (attr != null) 
     return attr.GPUShader; 
} 
return 0; 

的另一個問題是,如果它沒有找到,我應該怎麼回報? 0是可轉換爲任何枚舉,對嗎?這就是爲什麼我回來的原因。

忘了提及,上面的代碼爲每個枚舉成員返回0。

+1

可能重複://計算器.com/questions/5032774/what-attributetarget-should-i-use-for-enum-members) – 2011-02-23 22:14:02

+2

不,這是不同的。在這裏,我只是試圖使用反射來獲取在枚舉成員上設置的自定義屬性。 – 2011-02-23 22:16:40

+1

[獲取Enum的值的屬性]的可能的重複(http://stackoverflow.com/questions/1799370/getting-attributes-of-enums-value) – 2012-01-23 10:25:06

回答

26

這是一個有點亂做你正在嘗試做的,你必須使用反射:

public GPUShaderAttribute GetGPUShader(EffectType effectType) 
{ 
    MemberInfo memberInfo = typeof(EffectType).GetMember(effectType.ToString()) 
               .FirstOrDefault(); 

    if (memberInfo != null) 
    { 
     GPUShaderAttribute attribute = (GPUShaderAttribute) 
        memberInfo.GetCustomAttributes(typeof(GPUShaderAttribute), false) 
           .FirstOrDefault(); 
     return attribute; 
    } 

    return null; 
} 

這將返回GPUShaderAttribute,是有關一對EffectType枚舉值標記的實例。你必須把它的EffectType枚舉的特定值:

GPUShaderAttribute attribute = GetGPUShader(EffectType.MyEffect); 

一旦你的屬性的情況下,你可以得到的具體數值出它是對個人枚舉值標記的。

+0

謝謝你,它的工作原理。我不知道這會變得如此複雜。但這是最簡單的方法,對吧?你也知道爲什麼我的版本不起作用。我認爲,因爲枚舉不能被實例化,所以使用enum.getCustomAttributes會起作用。 – 2011-02-23 22:32:05

+1

@Joan:據我所知,這是最簡單的方法。你的方法不工作,因爲你正在獲取在枚舉類型上定義的屬性,而不是類型的值。 – adrianbanks 2011-02-23 22:35:31

+0

謝謝阿德里安,現在有道理。 – 2011-02-23 22:45:11

22

有泛型做到這一點的另一種方法:

public static T GetAttribute<T>(Enum enumValue) where T: Attribute 
{ 
    T attribute; 

    MemberInfo memberInfo = enumValue.GetType().GetMember(enumValue.ToString()) 
            .FirstOrDefault(); 

    if (memberInfo != null) 
    { 
     attribute = (T) memberInfo.GetCustomAttributes(typeof (T), false).FirstOrDefault(); 
     return attribute; 
    } 
    return null; 
} 
+1

我喜歡這個,但是沒有考慮到具有相同屬性的多個實例的可能性。我把你所擁有的修改爲使用T []而不是T,然後刪除GetCustomAttributes上的FirstOrDefault()。 – 2015-07-25 22:54:15

15

嘗試使用泛型方法

屬性:

class DayAttribute : Attribute 
{ 
    public string Name { get; private set; } 

    public DayAttribute(string name) 
    { 
     this.Name = name; 
    } 
} 

枚舉:

enum Days 
{ 
    [Day("Saturday")] 
    Sat, 
    [Day("Sunday")] 
    Sun, 
    [Day("Monday")] 
    Mon, 
    [Day("Tuesday")] 
    Tue, 
    [Day("Wednesday")] 
    Wed, 
    [Day("Thursday")] 
    Thu, 
    [Day("Friday")] 
    Fri 
} 

泛型方法:

 public static TAttribute GetAttribute<TAttribute>(this Enum value) 
     where TAttribute : Attribute 
    { 
     var enumType = value.GetType(); 
     var name = Enum.GetName(enumType, value); 
     return enumType.GetField(name).GetCustomAttributes(false).OfType<TAttribute>().SingleOrDefault(); 
    } 

調用:

 static void Main(string[] args) 
    { 
     var day = Days.Mon; 
     Console.WriteLine(day.GetAttribute<DayAttribute>().Name); 
     Console.ReadLine(); 
    } 

結果:

週一

[我應該使用什麼AttributeTarget爲枚舉成員?(HTTP的
+0

希望我可以upvote這個答案100次!好東西 :-) – Gericke 2018-03-01 20:44:10