views:

89

answers:

2

Say I have the following set of classes, is it possible for the attributes of DerivedClass to be merged? Currently if I use the GetType().GetCustomAttributes()method passing in true for inheritance it takes the highest attributes in the inheritance structure.

i.e. [Another("Bob")] and [My(16)]

Is it possible for the attributes to be merged? So I would end up with two attributes of [My(16, "Male")] and [Another("Bob")]

I don't mean to say that I would specify an attribute of [My(16, "Male")] but rather I would be returned an attribute with an Age of 16 and a Gender of Male.

public class MyAttribute : Attribute
{

    public MyAttribute(int age)
    {
        Age = age;
    }

    public MyAttribute(int age, string gender)
    {
        Age = age;
        Gender = gender;
    }

    public int Age { get; set; }

    public string Gender { get; set; }

}

public class AnotherAttribute : Attribute
{

    public AnotherAttribute(string name)
    {
        Name = name;
    }

    public string Name { get; set; }

}

[My(12, "Male")]
[Another("Bob")]
public class BaseClass
{
}

[My(16)]
public class DerivedClass : BaseClass
{
}
+2  A: 

You can have multiple instances of the same attribute on an entity (this is an option on the AttributeUsageAttribute applied to your attribute). When you get attributes on a type, you can get all the attributes applied to the inheritance chain.

However there is nothing in the standard tools that will take two attribute instances and make one.

(In theory a post processor that re-wrote the MSIL could do this.)

Richard
Thanks Richard that gets me a little closer. I was expecting to be able to get all the attributes and then have to merge them myself but was a little confused when I only got 2 attributes back so I couldn't even merge myself!
Craig Bovis
A: 

First, I don't believe any of the behavior you're inquiring about would depend on the AttributeUsage attribute which should be decorating your attribute classes (it looks like I could be wrong). Nor do I see where any attribute would be getting merged. Each attribute is a representation of a class in it's own right. Each attribute class should return it's own data. I would expect DerivedClass.GetCustomAttributes() to return three separate references for each attribute - 2 from the base class, and 1 for itself.

Try setting the AttributeUsage on the 'MyAttribute' to allow multiple. It may not be merging them, but taking the 'latest' version of the attribute.

I just thought of something else that could be causing the mysterious disappearing act. You may have to go after the base class to get the original attribute? You could try that:

base.GetType().GetCustomAttributes();

I did some digging and here is what the AttibuteUsage will do and could be causing you to only see one of the MyAttribute classes:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]

I was close in my statement earlier about using AttributeUsage; however, it is the Inherited named parameter that will limit visibility to the base class' MyAttribute decoration. Try specifying Inherited = true and see what you get.

dboarman
GetCustomAttributes is only returning two attributes. The AnotherAttribute from BaseClass and MyAttribute from DerivedClass. I was expecting 3 classes which would have allowed me to merge the attributes myself.
Craig Bovis