Как получить список свойств с заданным атрибутом?



у меня есть тип, t, и я хотел бы получить список публичных свойств, которые имеют атрибут MyAttribute. Атрибут помечен символом AllowMultiple = false, например:



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


В настоящее время у меня есть это, но я думаю, что есть лучший способ:



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


как я могу улучшить это? Мои извинения, если это дубликат, там есть тонна нитей отражения...похоже, это довольно горячая тема.

584   7  

7 ответов:

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

это позволяет избежать необходимости материализовать любые экземпляры атрибутов (т. е. это дешевле, чем GetCustomAttribute[s]().

решение я в конечном итоге с помощью всего зависит от ответа Томас Petricek по. Я обычно хочу сделать что-то с и атрибут и свойство.

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};

насколько я знаю, нет лучшего способа с точки зрения работы с библиотекой отражения более умным способом. Тем не менее, вы можете использовать LINQ, чтобы сделать код немного лучше:

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

// Do something with the properties in 'props'

Я считаю, что это поможет вам структурировать код более читаемым образом.

всегда есть LINQ:

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

Если вы часто имеете дело с атрибутами в отражении, это очень практично, чтобы определить некоторые методы расширения. Вы увидите, что во многих проектах там. Вот это у меня часто бывает:

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

который вы можете использовать как typeof(Foo).HasAttribute<BarAttribute>();

другие проекты (например, StructureMap) имеют полноценные классы ReflectionHelper, которые используют деревья выражений, чтобы иметь прекрасный синтаксис для идентификации, например, PropertyInfos. Использование тогда выглядит так:

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

В дополнение к предыдущим ответам: лучше использовать метод Any() вместо проверки длины коллекции:

propertiesWithMyAttribute = type.GetProperties()
  .Where(x => x.GetCustomAttributes(typeof(MyAttribute), true).Any());

пример в dotnetfiddle:https://dotnetfiddle.net/96mKep

лучше:

//if (attributes.Length == 1)
if (attributes.Length != 0)

Comments

    Ничего не найдено.