如何获取具有给定属性的属性列表?

时间:2010-02-17 15:35:22

标签: c# .net reflection

我有一个类型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
    }
}

我该如何改进?我很抱歉,如果这是重复的,那里有大量的反思线程......似乎这是一个非常热门的话题。

7 个答案:

答案 0 :(得分:351)

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

这避免了必须实现任何属性实例(即它比GetCustomAttribute[s]()便宜。

答案 1 :(得分:40)

我最终使用的解决方案基于Tomas 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};

答案 2 :(得分:32)

据我所知,在以更智能的方式使用Reflection库方面没有更好的方法。但是,您可以使用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'

我相信这有助于您以更易读的方式构建代码。

答案 3 :(得分:13)

总有LINQ:

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

答案 4 :(得分:5)

如果定期处理反射中的属性,定义一些扩展方法是非常非常实际的。你会在许多项目中看到它。这是我经常有的一个:

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

答案 5 :(得分:2)

除了之前的答案:最好使用方法Any()而不是检查集合的长度:

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

dotnetfiddle的例子:https://dotnetfiddle.net/96mKep

答案 6 :(得分:-4)

更好的方法:

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