Como faço para ler um atributo em uma class em tempo de execução?

Eu estou tentando criar um método genérico que irá ler um atributo em uma class e retornar esse valor em tempo de execução. Como eu faria isso?

Nota: O atributo DomainName é da class DomainNameAttribute.

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

O que estou tentando gerar:

 //This should return "MyTable" String DomainNameValue = GetDomainName(); 

 public string GetDomainName() { var dnAttribute = typeof(T).GetCustomAttributes( typeof(DomainNameAttribute), true ).FirstOrDefault() as DomainNameAttribute; if (dnAttribute != null) { return dnAttribute.Name; } return null; } 

ATUALIZAR:

Esse método poderia ser generalizado para funcionar com qualquer atributo:

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

e use assim:

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

Já existe uma extensão para fazer isso.

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

Assim:

 var attr = typeof(MyClass).GetCustomAttribute(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); } } 

Eu usei a resposta de Darin Dimitrov para criar uma extensão genérica para obter atributos de membro para qualquer membro de uma class (em vez de atributos para uma class). Estou postando aqui porque os outros podem achar útil:

 public static class AttributeExtensions { ///  /// Returns the value of a member attribute for any member in a class. /// (a member is a Field, Property, Method, etc...) ///  /// 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) ///  ///  /// Read System.ComponentModel Description Attribute from method 'MyMethodName' in class 'MyClass': /// var Attribute = typeof(MyClass).GetAttribute("MyMethodName", (DescriptionAttribute d) => d.Description); ///  /// The class that contains the member as a type /// Name of the member in the class /// Attribute type and property to get (will return first instance if there are multiple attributes of the same type) /// true to search this member's inheritance chain to find the attributes; otherwise, false. This parameter is ignored for properties and events ///  public static TValue GetAttribute(this Type type, string MemberName, Func 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); } } 

Exemplo de uso:

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

Aqui está um bom tutorial se você não viu antes http://msdn.microsoft.com/en-us/library/aa288454(VS.71).aspx

Em particular, de interesse para você é a seção aqui, chamada Acessando o Atributo http://msdn.microsoft.com/en-us/library/aa288454(VS.71).aspx#vcwlkattributestutorialanchor3

Uma versão simplificada da primeira solução de Darin Dimitrov:

 public string GetDomainName() { var dnAttribute = typeof(T).GetCustomAttribute(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 

Provavelmente tão fácil de usar o corpo de function genérica inline. Não faz nenhum sentido para mim tornar a function genérica sobre o tipo MyClass.

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