0

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.

ainwood
  • 992
  • 7
  • 17
  • I do not think there is any simpler way, [as this link](https://stackoverflow.com/a/6637710/6741868) also shows, the solution you're currently using seems to be the optimal one already. – Keyur PATEL Jul 25 '17 at 01:51
  • You can simplify it a little bit by using `TestAttribute thisAttribute = field_info.GetCustomAttribute(false);`. That cuts out the `object` array and the cast, but you still need the `PropertyInfo` (actually its base class `MemberInfo`) for the extension method. – Bradley Uffner Jul 25 '17 at 02:01

1 Answers1

1

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; }
}
Bradley Uffner
  • 16,641
  • 3
  • 39
  • 76