如何获得具有给定属性的属性列表?
我有一个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)