ainwood
ainwood

Reputation: 1048

Simpler way of accessing custom attributes?

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

Answers (1)

Bradley Uffner
Bradley Uffner

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

Related Questions