Custom Attributes
Tuesday, 22 June 2010
Article Index
Custom Attributes
Attribute semantics
Initialising fields
Practical attributes
An example
Solving the practical problems

Attribute semantics

The key to understanding what is going on here is to realise that the attribute class you have defined is instantiated when anything queries MyClass’s custom attributes.



To query custom attributes we use the GetCustomAttributes static method of the Attribute class:


This returns an array consisting of an instance of each attribute class corresponding to the attributes that have been applied to the specified type t.

For example the instruction:

Attribute[] attrs =Attribute.

returns an array with a single element attrs[0] which contains an instance of ASCII. A cast to ASCII is all you need to make use of the instance.

This way of retrieving attributes is the one you most often encounter in examples of attribute use. However, in many situations there is an alternative which is arguably better.

In most cases you don’t really want to retrieve all the attributes applied to an entity because you are writing code which is going to handle just one attribute type – i.e. the custom attribute you are currently implementing.

There is a fairly easy way to retrieve specific attributes from the type to which they are applied using the GetCustomAttribute method of the Type object to return attributes of a specified type.

For example, to retrieve any ASCII attributes applied to MyClass you would use:

object[] attrs=typeof(MyClass).
typeof(ASCII), false);

This returns an array of objects that can be cast to the attribute type you are looking for.The final Boolean parameter determines if the instances inheritance chain is searched for attributes - false restricts us to only directly applied attributes.

If you want to make things easier you can perform the cast on the returned array:

ASCII[] attrs=(ASCII[]) typeof(MyClass).
typeof(ASCII), false);

This always works because only attributes of ASCII type will be returned or a null reference which can also be cast to ASCII.

The attribute constructor

So far so good but currently the instance of the attribute’s class isn’t doing us a lot of good as the class has no methods and, more importantly, no properties.

There are two ways of providing it with properties. The first is to provide a constructor with parameters.

For example, if we change the ASCII class definition to:

public class ASCII : Attribute
public string MyData;
public ASCII(string MyDataIn)
MyData = MyDataIn;

we can pass some data to the class by applying the attribute as:

[ASCII("Hello Attribute World")]
public class MyClass

Now when the GetCustomAttributes method is called it returns a single instance of the ASCII class with MyData set to “Hello Attribute World”.

In other words, calling the GetCustomAttributes method has resulted in the class constructor being used with the data provided by the ASCII attribute tag.

The tag is a call to the constructor and you can think of:

[ASCII("Hello Attribute World") ]

as being equivalent to:

new ASCII("Hello Attribute World");

being executed when you call GetCustomAttributes on any class that the attribute is applied to so returning an instance complete with what ever initialisation the constructor has performed.

To see that you have indeed got an instance of the ASCII class complete with the string set by the constructor try:

ASCII[] attrs=(ASCII[]) typeof(MyClass).
typeof(ASCII), false);

After casting the returned array to ASCII you can access all its public methods and properties. While this isn’t the way that attributes are normally used it is perfectly valid.








Last Updated ( Friday, 27 August 2010 )

RSS feed of all content
I Programmer - full contents
Copyright © 2014 All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.