tags:

views:

246

answers:

5

I have a type, t, and I would like to get a list of the public properties that have the attribute MyAttribute.

Currently what I have is this, but I'm thinking there is a better way:

foreach (PropertyInfo prop in t.GetProperties())
{
    object[] attributes = prop.GetCustomAttributes(typeof(MyAttribute), true);
    if (attributes.Length == 1)
    {
         //Property with my custom attribute
    }
}

How can I improve this? My apologies if this is a duplicate, there are a ton of reflection threads out there...seems like it's quite a hot topic.

A: 

the better way:

if (attributes.Length == 1)
// |
// |
// |
//\|/
// .
if (attributes.Length != 0)
Behrooz
The attribute in question has AllowMultiple = false, so there is either 0 or 1. Should have specified that in my question.
wsanville
downvote?why? +(15 chars)
Behrooz
Dunno, wasn't me.
wsanville
+1  A: 

As far as I know, there isn't any better way in terms of working with Reflection library in a smarter way. However, you could use LINQ to make the code a bit nicer:

var props = from p in t.GetProperties()
            let attrs = prop.GetCustomAttributes(typeof(MyAttribute), true)
            where attrs.Length != 0 select p;

// Do something with the properties in 'props'

I believe this helps you to structure the code in a more readable fashion.

Tomas Petricek
+3  A: 

There's always LINQ:

t.GetProperties().Where(
    p=>p.GetCustomAttributes(typeof(MyAttribute), true).Length != 0)
P Daddy
A: 

If you deal regularly with Attributes in Reflection, it is very, very practical to define some extension methods. You will see that in many projects out there. This one here is one I often have:

public static bool HasAttribute<T>(this ICustomAttributeProvider provider) where T : Attribute
{
  var atts = provider.GetCustomAttributes(typeof(T), true);
  return atts.Length > 0;
}

which you can use like typeof(Foo).HasAttribute<BarAttribute>();

Other projects (e.g. StructureMap) have full-fledged ReflectionHelper classes that use Expression trees to have a fine syntax to identity e.g. PropertyInfos. Usage then looks like that:

ReflectionHelper.GetProperty<Foo>(x => x.MyProperty).HasAttribute<BarAttribute>()
flq
+5  A: 
var props = t.GetProperties().Where(
                prop => Attribute.IsDefined(prop, typeof(MyAttribute)));

This avoids having to materialize any attribute instances (i.e. it is cheaper than GetCustomAttribute[s]().

Marc Gravell
Good suggestion. I will however need the attribute instance, but I like it.
wsanville