2012-01-07 26 views
8

Mam sytuację, jak następuje:C# - Sprawdzenie istnienia atrybutu na ENUM jest elementem

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

muszę uzyskać szereg elementów, na których OldProtocolAttribute jest zdefiniowana. Zauważyłem, że metoda Attribute.IsDefined() i jej przeciążenia najwyraźniej nie obsługują tego rodzaju sytuacji.

Moje pytanie brzmi:

  • Czy istnieje sposób, aby rozwiązać problem bez użycia w dowolnej części roztworu typeof(Header).GetField()?
  • Jeśli nie, jaki jest najbardziej optymalny sposób rozwiązania tego problemu?

Odpowiedz

14

O ile mi wiadomo, musisz uzyskać atrybut z pola. Można by użyć:

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

lub uzyskać cały szereg:

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

Oczywiście jeśli trzeba to często, można również chcą buforować wyniki.

+0

Doskonale, dzięki! – user1098567

+0

@Jon Skeet, brakuje ci ")" po ".Where (field => field.IsDefined (attributeType, false)" - ten kod się nie skompiluje –

+0

@ nucleicsweet: Naprawiono, dziękuję. –

4

Odbicie jest prawie jedynym dostępnym narzędziem do tego. Zapytanie nie jest jednak takie złe:

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