2010-08-06 21 views
21

Questo può sembrare un po 'capovolto, ma quello che voglio essere in grado di fare è ottenere un valore enum da un enum dal suo attributo Descrizione.Trovare un valore enum con Descrizione Attributo

Quindi, se ho un enum dichiarato come segue:

enum Testing 
{ 
    [Description("David Gouge")] 
    Dave = 1, 
    [Description("Peter Gouge")] 
    Pete = 2, 
    [Description("Marie Gouge")] 
    Ree = 3 
} 

Mi piacerebbe essere in grado di ottenere 2 indietro fornendo la stringa "Peter Gouge".

Come punto di partenza, posso scorrere i campi enum e afferrare il campo con l'attributo corretto:

string descriptionToMatch = "Peter Gouge"; 
FieldInfo[] fields = typeof(Testing).GetFields(); 

foreach (FieldInfo field in fields) 
{ 
    if (field.GetCustomAttributes(typeof(DescriptionAttribute), false).Count() > 0) 
    { 
     if (((DescriptionAttribute)field.GetCustomAttributes(typeof(DescriptionAttribute), false)[0]).Description == descriptionToMatch) 
     { 

     } 
    } 
} 

Ma poi mi sono bloccato su cosa fare in quella interna, se. Inoltre non sono sicuro se questa è la strada da percorrere in primo luogo.

risposta

27

Utilizzando il metodo di estensione descritto here:

Testing t = Enum.GetValues(typeof(Testing)) 
       .Cast<Testing>() 
       .FirstOrDefault(v => v.GetDescription() == descriptionToMatch); 

Se non viene trovato nessun valore corrispondente, verrà restituito (Testing)0 (si potrebbe desiderare di definire un membro None nella vostra enum per questo valore)

+1

Ah, LINQ ancora una volta in soccorso. Mi piace davvero questa soluzione, grazie! – DavidGouge

+0

-1: oggetti extra creati in questo codice: 1) un RuntimeType, 2) un cast-iterator, 3) un oggetto lambda, 4) un WhereIterator. Oggetti extra creati con la soluzione di Ani; nessuna. – Henrik

+0

@ Henrik, stai solo dimenticando una cosa: la soluzione di Ani presuppone che tu abbia già FieldInfo, e devi usare il reflection per ottenerlo ... La mia soluzione non usa la reflection; GetValues ​​è implementato internamente con codice nativo, quindi è molto più veloce dell'utilizzo del reflection (almeno 5 volte più veloce secondo i miei test). Il costo di creare un RuntimeType e un WhereIterator è trascurabile rispetto alla riflessione. Per quanto riguarda "l'oggetto lambda", non esiste una cosa del genere ... è solo un metodo anonimo creato nel tipo corrente. –

1

Ok, dopo aver digitato tutto ciò, penso che questo sia il caso di una decisione all'inizio che mi porta sulla strada sbagliata. Enum sembrava il modo giusto per iniziare, ma un semplice Dictionary<string, int> sarà sufficiente e sarà molto più facile lavorare con!

4
return field.GetRawConstantValue(); 

Ovviamente è possibile ricondurlo a Test, se necessario.

+1

Eccellente, grazie. – DavidGouge

+0

Sembra promettente, ma non funziona. Ottengo un 'InvalidOperationException':" L'operazione non è valida a causa dello stato attuale dell'oggetto. " –

+0

Basta dare un'occhiata in Reflector: l'unica classe che implementa effettivamente questo metodo è 'MdFieldInfo'. In 'RtFieldInfo', lancia solo un'eccezione InvalidOperationException. –

Problemi correlati