Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inheritance of C# attribute classes

How does inheritance of attribute classes work in C#? To clarify, I am talking about the inheritance of the attribute classes themselves (i.e. base classes of System.Attributes), NOT any classes that happen to have them as attribute.

For some reason, I cannot seem to find anything on this (my searches always turn up with the other meaning).

For example, if a have a class AttributeA which extends System.Attribute:

  1. Do I have to separately mark subclasses of AttributeA with [AttributeUsage()]. (Since System.AttributeUsage's inheritance is true, I don't think I will.)

  2. Will AllowMultiple=false on the AttributeUsage of AttributeA prevent me from having multiple subclasses of AttributeA for attributes?

EDIT:

Programmers can only read code.

[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
class AttributeA
{ }

class AttributeB : AttributeA
{ }

class AttributeC : AttributeA
{ }

[AttributeB]
[AttributeC]
class Foo
{ }

Does this work?

like image 767
Paul Draper Avatar asked Apr 19 '13 22:04

Paul Draper


2 Answers

(I was finally able to try it.)

The example code does compile. I still like to have documentation, although I suppose C# is C# and it isn't going to change that. (Right?)

Evidently:

  1. The subclasses inherit AttributeUsage, as expected.
  2. AllowMultiple refers only to attributes of (strictly) the original class, not subclasses.
  3. Also, AttributeUsage can be effectively "re-defined".

With

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
class AttributeA : Attribute
{ }

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
class AttributeB : AttributeA
{ }

class AttributeC : AttributeA
{ }

the following is okay

[AttributeA]
[AttributeB]
[AttributeB]
[AttributeC]
class Foo
{ }

but this isn't

[AttributeA]
[AttributeB]
[AttributeC]
[AttributeC]
class Foo
{ }
like image 140
Paul Draper Avatar answered Sep 20 '22 11:09

Paul Draper


You can control this behavior by using the named parameter Inherited for your AttributeUsageAttribute.

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
class AttributeA
{ }

class AttributeB : AttributeA
{ }

class AttributeC : AttributeA
{ }
like image 39
Christopher von Blum Avatar answered Sep 20 '22 11:09

Christopher von Blum