201 votes

Comment obtenir une liste de propriétés avec un attribut donné?

J'ai un type, t, et j'aimerais obtenir une liste des propriétés publiques qui ont l'attribut MyAttribute. L'attribut est marqué avec AllowMultiple = false, comme ceci:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]

Actuellement ce que j'ai est ce, mais je pense que il ya une meilleure façon:

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

Comment puis-je améliorer cela? Toutes mes excuses si c'est un doublon, il y a une tonne de réflexion fils...il me semble qu'il est tout à fait un sujet chaud.

371voto

Marc Gravell Points 482669
var props = t.GetProperties().Where(
                prop => Attribute.IsDefined(prop, typeof(MyAttribute)));

Cela évite d'avoir à se matérialiser n'importe quel attribut cas (c'est à dire qu'il est moins cher que d' GetCustomAttribute[s]().

42voto

wsanville Points 22066

La solution que j'ai fini par utiliser la plupart est basé hors de Tomas Petricek de réponse. J'ai l'habitude de vouloir faire quelque chose avec à la fois l'attribut et de la propriété.

var props = from p in this.GetType().GetProperties()
            let attr = p.GetCustomAttributes(typeof(MyAttribute), true)
            where attr.Length == 1
            select new { Property = p, Attribute = attr.First() as MyAttribute};

33voto

Tomas Petricek Points 118959

Autant que je sache, il n'y a pas une meilleure façon en termes de travail, de Réflexion, de la bibliothèque de façon plus intelligente. Toutefois, vous pouvez utiliser LINQ pour rendre le code un peu plus agréable:

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'

Je crois que cela vous aide à structurer le code plus lisible de la mode.

13voto

P Daddy Points 14228

Il y a toujours LINQ:

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

6voto

flq Points 11937

Si vous travaillez régulièrement avec des Attributs dans la Réflexion, il est très, très pratique pour définir des méthodes d'extension. Vous verrez que dans de nombreux projets. Celui-ci est celui que j'ai souvent:

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

que vous pouvez utiliser comme typeof(Foo).HasAttribute<BarAttribute>();

D'autres projets (p. ex. StructureMap) ont à part entière ReflectionHelper les classes qui utilisent des arbres d'Expression à un bel syntaxe d'identité par exemple PropertyInfos. L'utilisation ensuite ressemble à ça:

ReflectionHelper.GetProperty<Foo>(x => x.MyProperty).HasAttribute<BarAttribute>()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X