2017-07-25 55 views
0

我有一个称为“InfoTest”的“Form1”类的属性,它具有一些我想要访问的自定义属性。访问自定义属性的更简单方法?

的代码工作正常,但它是一个有点笨拙:

[Test("foo",15)] 
    public double InfoTest { get; set; } 

    public void RetrieveAttribute() 
    { 
     PropertyInfo field_info = typeof(Form1).GetProperty("InfoTest"); 
     object[] custom_attributes = field_info.GetCustomAttributes(typeof(TestAttribute), false); 
     TestAttribute thisAttribute = (TestAttribute)custom_attributes[0]; 
     Debug.WriteLine(thisAttribute.Info + "," + thisAttribute.TheValue); 
    } 

我相信答案是“否”,但有可能得到InfoTest属性的一个更简单的方法,即不涉及`typeof运算(Form1上).GetProperty( “InfoTest”)?我不能去(例如):

var runtimePropInfo = InfoTest.GetType().GetRuntimeProperties(); 
    var propInfo = InfoTest.GetType().GetProperties(); 

...这基本上是因为它试图得到一个“双”,而不是“InfoTest”对象的属性。

+0

我不认为有什么简单的办法,[因为这链接](https://stackoverflow.com/a/6637710/6741868)也显示,该解决方案你目前使用的似乎已经是最佳的了。 –

+0

你可以通过使用'TestAttribute thisAttribute = field_info.GetCustomAttribute (false);'来简化它。这会删除'object'数组和cast,但您仍然需要'PropertyInfo'(实际上它的基类'MemberInfo')作为扩展方法。 –

回答

1

仅依靠内置函数,您可以使用an extension methodMemberInfo)上的来简化它,它可以直接返回自定义属性。

PropertyInfo field_info = typeof(Form1).GetProperty("InfoTest"); 
TestAttribute thisAttribute = field_info.GetCustomAttribute<TestAttribute>(false); 
Debug.WriteLine(thisAttribute.Info + "," + thisAttribute.TheValue); 

这摆脱了object阵列和类型转换。

如果您愿意使用自定义扩展方法,则可以使用此扩展方法将其简化为一个函数调用。它具有强类型的好处,尽管它可能不如表示。

public static class ReflectionExtensions 
{ 
    public static TAttribute GetAttribute<TAttribute, TClass>(this TClass target, Expression<Func<TClass, object>> targetProperty) where TAttribute : Attribute 
    { 
     var lambda = (LambdaExpression) targetProperty; 
     var unaryExpression = (UnaryExpression) lambda.Body; 
     string name = ((MemberExpression) unaryExpression.Operand).Member.Name; 
     MemberInfo info = typeof(TClass).GetProperty(name); 

     return info.GetCustomAttribute<TAttribute>(false); 
    } 
} 

它可以在任何使用(它是object的扩展名)是这样的:

var attr = thing.GetAttribute<TestAttribute, Thing>(obj => obj.InfoTest); 

它从thingInfoTest属性,它是Thing类的实例得到TestAttribute

Thing被定义为:

public class Thing 
{ 
    [Test("foo", 15)] 
    public double InfoTest { get; set; } 
}