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


Initialising fields

As well as using the constructor to initialise the instance, you can also use named parameters to initialise member variables. For example, if we add a public variable MoreData to the attribute class:

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

it can be initialised using:

[ASCII("Hello Attribute World",

Now when GetCustomAttributes is called the instance is constructed as follows:

attrs[0]=new ASCII(
"Hello Attribute World");
attrs[0].MoreData = "SomeData";

Once again you can test this assertion by using a MessageBox:

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

where you will discover that the public string MoreData has indeed been set to “SomeData” by the attribute.

You should now be able to see the general principle:.

  • Any unnamed parameters used in the attribute are passed to the constructor in the order in which they are given.
  • Any named parameters are used as initialisation statements after the instance has been constructed.

Notice that all of the unnamed parameters have to come before the named parameters. So for example, an attribute applied as:


results in:

MyAttribute MyInstance=new

when the GetCustomAttributes method is used.

Notice also that named parameters are optional, if they are not supplied then the corresponding variable is left uninitialised.

It is also important to know that the type of parameter you can use is limited to the majority of the simple types, i.e. int, long, float, string, System.Type, object, a publicly accessible enum and a one-dimensional array of any allowable type.

You might think that as you can pass an object you can pass anything but this isn’t the case. There is an additional condition that restricts parameters to constants of the appropriate type.

So you can have:

[ASCII("Hello Method",MyObject=1)]

and even:

[ASCII("Hello Method",MyObject="Hello")] 

but you can’t have:

[ASCII("Hello Method",
MyObject=new object())]

or anything like it.

Each time you request the details of an attribute a new object is instantiated no matter what class is involved.

  So for example, if we go back to the simpler version of ASCII with a single parameter constructor, the following:

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

does indeed create distinct attribute instances as you can demonstrate:

ASCII[] attrs1=(ASCII[])typeof(MyClass).
typeof(ASCII), false);
ASCII[] attrs2=(ASCII[])typeof(MyClass2).
typeof(ASCII), false);

The result is two messageboxes that correctly show each of the messages set by the attribute tags.

However you get two instances even if you call GetCustomAttributes a second time on the same class.

What isn’t generally realised is that you can change attribute values fairly easily at runtime. The reason is, of course, that the instances of the attribute classes that are created are perfectly normal objects and can be used without restriction. For example, we can get the object:

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

change the value of its public variable and show that it has changed:

attrs1[0].MyData="A New String";

and finally create another instance and show that its value is unchanged:

ASCII[] attrs3=(ASCII[])
typeof(ASCII), false);









Last Updated ( Friday, 27 August 2010 )

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