2011-02-23 26 views
28

Ho un enum in cui a ogni membro è applicato un attributo personalizzato. Come posso recuperare il valore memorizzato in ogni attributo?Come ottenere i valori degli attributi personalizzati per le enumerazioni?

In questo momento faccio questo:

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

Un altro problema è, se non è trovato, cosa devo tornare? 0 è implcità convertibile in qualsiasi enum, giusto? Ecco perché l'ho restituito.

Dimenticato di menzionare, il codice sopra riportato restituisce 0 per ogni membro di enum.

+1

possibile duplicato del [Cosa AttributeTarget dovrei usare per i membri enum?] (Http: // StackOverflow .com/questions/5032774/what-attributetarget-should-i-use-for-enum-members) –

+2

Non è diverso. Qui sto solo cercando di ottenere gli attributi personalizzati impostati su un membro di enum usando la reflection. –

+1

possibile duplicato di [Ottenere attributi del valore di Enum] (http://stackoverflow.com/questions/1799370/getting-attributes-of-enums-value) –

risposta

26

E 'un po' disordinato di fare ciò che si sta cercando di fare come si deve usare riflessione:

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; 
} 

Questo restituirà un'istanza della GPUShaderAttribute che è rilevante per quella contrassegnata sul valore enumerazione di EffectType. Bisogna chiamare su un valore specifico del EffectType enum:

GPUShaderAttribute attribute = GetGPUShader(EffectType.MyEffect); 

Una volta che avete l'istanza dell'attributo, è possibile ottenere i valori specifici da esso che sono contrassegnati-up sui singoli valori enum.

+0

Grazie amico, funziona. Non sapevo che sarebbe stato così complicato. Ma questo è il modo più semplice, giusto? Sai anche perché la mia versione non ha funzionato. Ho pensato che non potendo istanziare le enumerazioni, usare enum.getCustomAttributes funzionerebbe. –

+1

@ Joan: questo è il modo più semplice che conosca. Il tuo metodo non ha funzionato mentre stavi ottenendo gli attributi definiti sul tipo enum invece che sui valori del tipo. – adrianbanks

+0

Grazie Adrian, ha senso ora. –

22

V'è un altro metodo per fare questo con i generici:

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

Mi piace, ma non tiene conto della possibilità di avere più istanze dello stesso attributo. Ho preso quello che avevi e lo ho modificato per usare T [] invece di T, quindi ho rimosso il FirstOrDefault() su GetCustomAttributes. –

15

provare a utilizzare un metodo generico

Attributo:

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

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

Enum:

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

metodo generico :

 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(); 
    } 

Invoke:

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

Risultato:

Lunedi

+0

Vorrei poter revocare questa risposta 100 volte !! Grandi cose :-) – Gericke

Problemi correlati