C# - Check for attribute's existence on enum's element
Asked Answered
E

2

15

I've got a situation like the following:

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

I need to obtain an array of elements on which the OldProtocolAttribute is defined. I've noticed that the Attribute.IsDefined() method and its overloads apparently don't support this kind of situation.

My question is:

  • Is there a way to solve the problem without using in any part of the solution typeof(Header).GetField()?
  • If not, what's the most optimal way to solve it?
Eyeleen answered 7/1, 2012 at 17:0 Comment(0)
C
28

As far as I'm aware, you have to get the attribute from the field. You'd use:

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

Or to get a whole array:

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

Obviously if you need this often, you may well want to cache the results.

Catkin answered 7/1, 2012 at 17:3 Comment(3)
@Jon Skeet, u miss ")" after ".Where(field => field.IsDefined(attributeType, false)" - this code will not compile.Tresa
Actually it will cache internally.Vulgarism
@AridaneÁlamo: IsDefined may cache, but if the OP needs the whole array of fields frequently, it would be worth caching that.Catkin
G
5

Reflection is pretty much your only tool available for this. The query is not too bad though:

var oldFields = typeof(Header).GetFields(BindingFlags.Static | BindingFlags.Public).Select(field => Attribute.IsDefined(field, typeof(OldProtocolAttribute)));
Grayback answered 7/1, 2012 at 17:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.