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

我有一个types, 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 } } 

我怎样才能改善这个? 我很抱歉,如果这是重复的,那里有很多reflection线程…似乎这是一个相当热门的话题。

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

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

我最常使用的解决scheme是基于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}; 

据我所知,在用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' 

我相信这可以帮助您以更可读的方式构build代码。

总是有LINQ:

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

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

 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类,它们使用expression式树来具有很好的语法来标识PropertyInfos。 用法如下所示:

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

更好的方法是:

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