I'm working with custom attributes, which again have a common base class. The AttributeUsage attribute is declared on the base attribute class, not on the concrete attribute classes.
My attribute usage on the base class says
AttributeTargets.Class, AllowMultiple = true, Inherited = true
Now when i'm working with my concrete attribute classes they use the AttributeUsage settigs from the base attribute class for Target and AllowMultiple, but not for Inherited -> this does not make any sense for me.
Here's a little code example which does not output what i expect:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public abstract class TestAttributeBase : Attribute
{
}
public class TestAttribute : TestAttributeBase
{
public string Value {get; private set;}
public TestAttribute(string value)
{
Value = Value;
}
}
[TestAttribute("A")]
public class A {
}
[TestAttribute("B")]
[TestAttribute("C")]
public class B : A
{
}
public static void Main()
{
var customAttributes = typeof(B).GetCustomAttributes<TestAttributeBase>(true).ToList();
Console.WriteLine(customAttributes.Count);
}
Here's the dotnetfiddle Link with the same code: https://dotnetfiddle.net/BZ7R4S
If you run this code it outputs "2", but i would expect "3".
The [AttributeUsage]
of TestAttributeBase
is definetly inherited to the TestAttribute
, because if you change AttributeTargets.Class
to e.g. AttributeTargets.Field
, the code does not compile. If you set AllowMultiple
to false
the code does not compile -> I discern from this that [AttributeUsage]
gets inherited to the concrete Attribute
classes, but not the Inherited
property.
Does this make any sense?
If i add the exact same [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
to the concrete TestAttribute
, it works and ouputs 3
The issue was posted closed as "won't fix" with the following comment:
Even it sounds like a bug fixing this now probably quite breaking as it was like this from the beginning. Given that there is a workaround: add your own
[AttributeUsage]
instead of assuming the base class's will be used closing the issue as not planned
So the only option is to apply the attribute to the derived class:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class TestAttribute : TestAttributeBase
{
// ...
}