Accessing a custom attribute from within an instanced object

446 views Asked by At

I'm trying to find a way to get access to attributes which have been applied at the property level from within an object, but am hitting a brick wall. It appears that the data is stored at the type level, but I need it at the property level.

Here's an example of what I'm trying to make:

public class MyClass
{
    [MyAttribute("This is the first")]
    MyField First;
    [MyAttribute("This is the second")]
    MyField Second;
}

public class MyField
{
    public string GetAttributeValue()
    {
        // Note that I do *not* know what property I'm in, but this
        // should return 'this is the first' or 'this is the second',
        // Depending on the instance of Myfield that we're in.
        return this.MyCustomAttribute.value;  
    }
}
1

There are 1 answers

3
plinth On BEST ANSWER

Attributes aren't used that way. Attributes are stored in the class object that contains the attribute, not the member object/field that is declared within the class.

Since you want this to be unique per member, it feels more like this should be member data with MyField, something passed in by the constructor.

If you're hell bent on using an attribute, you could add code in your constructor that used reflection on every member that has an attribute attached to it an attempts to set its instance data to what you want, but you would need to make sure that all your MyField objects are fully constructed.

Alternately you could make your setter look like this:

private MyField _first;
[MyAttribute("This is the first")]
public MyField First {
    get { return _first; }
    set {
        _first = value;
        if (_first != null) {
            _first.SomeAttribute = GetMyAttributeValue("First");
        }
    }
 }

 private string GetMyAttributeValue(string propName)
 {
     PropertyInfo pi = this.GetType().GetPropertyInfo(propName);
     if (pi == null) return null;
     Object[] attrs = pi.GetCustomAttributes(typeof(MyAttribute));
     MyAttribute attr =  attrs.Length > 0 ? attrs[0] as MyAttribute : null;
     return attr != null ? attr.Value : null;
 }