Reputation: 1048
I have a property of the "Form1" class called "InfoTest" that has some custom attributes that I want to access.
The code works fine, but is a bit unwieldy:
[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);
}
I presume the answer is "No", but is there a simpler way of getting the attributes for InfoTest, that doesn't involve the `typeof(Form1).GetProperty("InfoTest")? I can't go (for example):
var runtimePropInfo = InfoTest.GetType().GetRuntimeProperties();
var propInfo = InfoTest.GetType().GetProperties();
...Which is essentially because it is trying to get the properties of a "double", not a "InfoTest" object.
Upvotes: 0
Views: 450
Reputation: 17001
Just relying on built-in functions, you can simplify it a bit by using an extension method on MemberInfo
that can directly return a custom attribute.
PropertyInfo field_info = typeof(Form1).GetProperty("InfoTest");
TestAttribute thisAttribute = field_info.GetCustomAttribute<TestAttribute>(false);
Debug.WriteLine(thisAttribute.Info + "," + thisAttribute.TheValue);
That gets rid of an object
array, and a type-cast.
If you are willing to use a custom extension method, you can use this one to simplify it to one function call. It has the benefit of being strongly typed, though it may not be as performant.
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);
}
}
It can be used on anything (it's an extension of object
) like this:
var attr = thing.GetAttribute<TestAttribute, Thing>(obj => obj.InfoTest);
It gets the TestAttribute
from the InfoTest
property of thing
, which is an instance of the Thing
class.
Thing
is defined as:
public class Thing
{
[Test("foo", 15)]
public double InfoTest { get; set; }
}
Upvotes: 1