2012-01-07 12 views
8

Ho una situazione simile alla seguente:C# - Verificare l'esistenza di attributo elemento di enum

enum Header 
{ 
    Sync, 
    [OldProtocol] Keepalive, 
    Ping, 
    [OldProtocol] Auth, 
    [OldProtocol] LoginData 
    //... 
} 

Ho bisogno di ottenere una serie di elementi su cui la OldProtocolAttribute è definito. Ho notato che il metodo Attribute.IsDefined() e i suoi sovraccarichi non supportano questo tipo di situazione.

La mia domanda è:

  • C'è un modo per risolvere il problema senza l'utilizzo in qualsiasi parte della soluzione typeof(Header).GetField()?
  • In caso contrario, qual è il modo migliore per risolverlo?

risposta

14

Per quanto ne so, è necessario ottenere l'attributo dal campo. Devi usare:

var field = typeof(Header).GetField(value.ToString()); 
var old = field.IsDefined(typeof(OldProtocolAttribute), false); 

o per avere tutta una serie:

var attributeType = typeof(OldProtocolAttribute); 
var array = typeof(Header).GetFields(BindingFlags.Public | 
            BindingFlags.Static) 
          .Where(field => field.IsDefined(attributeType, false)) 
          .Select(field => (Header) field.GetValue(null)) 
          .ToArray(); 

Ovviamente se avete bisogno di questo, spesso, ci si vorrà mettere in cache i risultati.

+0

Perfetto, grazie! – user1098567

+0

@Jon Skeet, manchi ")" dopo ".Where (field => field.IsDefined (attributeType, false)" - questo codice non verrà compilato –

+0

@nuclearsweet: risolto, grazie. –

4

Reflection è praticamente il tuo unico strumento disponibile per questo. La domanda non è poi così male:

var oldFields = typeof(Header).GetFields(BindingFlags.Static | BindingFlags.Public).Select(field => Attribute.IsDefined(field, typeof(OldProtocolAttribute)));