클래스의 속성을 읽고 런타임에 해당 값을 반환하는 일반 메서드를 만들려고합니다. 어떻게해야합니까?
참고 : 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의 답변을 사용하여 클래스의 모든 멤버에 대한 멤버 속성을 가져 오는 일반 확장을 만들었습니다 (클래스의 속성 대신). 다른 사람들이 유용하다고 생각할 수 있기 때문에 여기에 게시하고 있습니다.
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);
답변
Darin Dimitrov의 첫 번째 솔루션의 단순화 된 버전 :
public string GetDomainName<T>()
{
var dnAttribute = typeof(T).GetCustomAttribute<DomainNameAttribute>(true);
if (dnAttribute != null)
{
return dnAttribute.Name;
}
return null;
}
답변
http://msdn.microsoft.com/en-us/library/aa288454(VS.71).aspx 전에 본 적이없는 경우 좋은 자습서가 있습니다 .
특히 관심있는 부분은 속성 액세스 http://msdn.microsoft.com/en-us/library/aa288454(VS.71).aspx#vcwlkattributestutorialanchor3 라는 섹션입니다
.
답변
' 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
아마도 일반 함수의 본문을 인라인으로 사용하기 쉽습니다. MyClass 유형에 대해 일반 함수를 만드는 것은 나에게 의미가 없습니다.
string DomainName = GetAttribute<DomainNameAttribute>(typeof(MyClass)).Name
// null reference exception if MyClass doesn't have the attribute.