如何在运行时读取类上的属性?

我想创build一个通用的方法,将读取一个类的属性,并在运行时返回该值。 我该怎么做?

注意:DomainName属性属于DomainNameAttribute类。

[DomainName("MyTable")] Public class MyClass : DomainBase {} 

我想要生成的是:

 //This should return "MyTable" String DomainNameValue = GetDomainName<MyClass>(); 
 public string GetDomainName<T>() { var dnAttribute = typeof(T).GetCustomAttributes( typeof(DomainNameAttribute), true ).FirstOrDefault() as DomainNameAttribute; if (dnAttribute != null) { return dnAttribute.Name; } return null; } 

更新:

这个方法可以进一步推广到任何属性:

 public static class AttributeExtensions { public static TValue GetAttributeValue<TAttribute, TValue>( this Type type, Func<TAttribute, TValue> valueSelector) where TAttribute : Attribute { var att = type.GetCustomAttributes( typeof(TAttribute), true ).FirstOrDefault() as TAttribute; if (att != null) { return valueSelector(att); } return default(TValue); } } 

并像这样使用:

 string name = typeof(MyClass) .GetAttributeValue((DomainNameAttribute dna) => dna.Name); 

已经有一个扩展来做到这一点。

 namespace System.Reflection { // Summary: // Contains static methods for retrieving custom attributes. public static class CustomAttributeExtensions { public static T GetCustomAttribute<T>(this MemberInfo element, bool inherit) where T : Attribute; } } 

所以:

 var attr = typeof(MyClass).GetCustomAttribute<DomainNameAttribute>(false); return attr != null ? attr.DomainName : ""; 
 System.Reflection.MemberInfo info = typeof(MyClass); object[] attributes = info.GetCustomAttributes(true); for (int i = 0; i < attributes.Length; i++) { if (attributes[i] is DomainNameAttribute) { System.Console.WriteLine(((DomainNameAttribute) attributes[i]).Name); } } 

我用Darin Dimitrov的答案来创build一个通用的扩展来获取类中的任何成员的成员属性(而不是类的属性)。 我在这里发布,因为其他人可能会觉得它有用:

 public static class AttributeExtensions { /// <summary> /// Returns the value of a member attribute for any member in a class. /// (a member is a Field, Property, Method, etc...) /// <remarks> /// If there is more than one member of the same name in the class, it will return the first one (this applies to overloaded methods) /// </remarks> /// <example> /// Read System.ComponentModel Description Attribute from method 'MyMethodName' in class 'MyClass': /// var Attribute = typeof(MyClass).GetAttribute("MyMethodName", (DescriptionAttribute d) => d.Description); /// </example> /// <param name="type">The class that contains the member as a type</param> /// <param name="MemberName">Name of the member in the class</param> /// <param name="valueSelector">Attribute type and property to get (will return first instance if there are multiple attributes of the same type)</param> /// <param name="inherit">true to search this member's inheritance chain to find the attributes; otherwise, false. This parameter is ignored for properties and events</param> /// </summary> public static TValue GetAttribute<TAttribute, TValue>(this Type type, string MemberName, Func<TAttribute, TValue> valueSelector, bool inherit = false) where TAttribute : Attribute { var att = type.GetMember(MemberName).FirstOrDefault().GetCustomAttributes(typeof(TAttribute), inherit).FirstOrDefault() as TAttribute; if (att != null) { return valueSelector(att); } return default(TValue); } } 

用法示例:

 //Read System.ComponentModel Description Attribute from method 'MyMethodName' in class 'MyClass' var Attribute = typeof(MyClass).GetAttribute("MyMethodName", (DescriptionAttribute d) => d.Description); 

这是一个很好的教程,如果你还没有看到它之前http://msdn.microsoft.com/en-us/library/aa288454(VS.71).aspx

特别感兴趣的是这里的部​​分,称为访问属性http://msdn.microsoft.com/en-us/library/aa288454(VS.71).aspx#vcwlkattributestutorialanchor3

Darin Dimitrov的第一个解决scheme的简化版本:

 public string GetDomainName<T>() { var dnAttribute = typeof(T).GetCustomAttribute<DomainNameAttribute>(true); if (dnAttribute != null) { return dnAttribute.Name; } return null; } 
 ' Simplified Generic version. Shared Function GetAttribute(Of TAttribute)(info As MemberInfo) As TAttribute Return info.GetCustomAttributes(GetType(TAttribute), _ False).FirstOrDefault() End Function ' Example usage over PropertyInfo Dim fieldAttr = GetAttribute(Of DataObjectFieldAttribute)(pInfo) If fieldAttr IsNot Nothing AndAlso fieldAttr.PrimaryKey Then keys.Add(pInfo.Name) End If 

可能就像在线使用generics函数的主体一样简单。 对MyClasstypes来说,我没有任何意义。

 string DomainName = GetAttribute<DomainNameAttribute>(typeof(MyClass)).Name // null reference exception if MyClass doesn't have the attribute.