- bool, byte, char, double, float, int, long, short, string
- System. Type
- object
- An enum type, provided that it and any types in which it is nested are publicly accessible-as in the example used with the RegistryHives enumeration
- A one-dimensional array involving any of the types listed above
Because the parameter types are limited to the types in this list, you can't pass data structures like classes to the attribute constructor. This restriction makes sense because attributes are attached at design time and you wouldn't have the instantiated instance of the class (an object) at that point. With the valid types listed above, you can hard-code their values at design time, which is why they can be used.
The AttributeUsage Attribute
In addition to custom attributes that you use to annotate regular C# types, you can use the AttributeUsage attribute to define how you want these attributes to be used. The AttributeUsage attribute has the following documented calling conventions: -
[AttributeUsage( validon, AllowMultiple = allowmultiple, Inherited = inherited )]
As you can see, it's easy to discern which are positional parameters and which are named parameters. I would strongly recommend that you document your attributes in this fashion so that the user of your attribute doesn't need to look through your attribute class's source code to find the public read/write fields and properties that can be used as named attributes.