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

Banner

An example

It is very difficult to find a convincing practical example that uses attributes that is general enough to convey the principles and ideas.

If you look at the way attributes are used in C# and in the Framework you will soon discover that they have a limited application without extending the way that they behave to affect the compiler.Of course using custom attributes you can’t do this.

Some built-in attributes do give you a good idea of what they are good at without extra tricks. For example, the whole p/invoke and com interop marshaling of parameters is a perfect example. You apply marshaling attribute tags to the parameters of external methods you want to call and when you use them the Framework/CLR uses these attributes to decide how to transform managed data into the correct unmanaged data and vice versa.

What makes this a good use of attributes is that the marshaling has to be applied at the class level and once applied isn’t going to be changed at the instance level, and the code that processes the instances can keep all of the mechanisms that load and respond to the attributes applied hidden from view. As far as the user of the attributes is concerned it’s a matter of applying the attribute, then ignoring it in all the code they write but when they use some supplied machinery the attribute makes it work correctly.

Consider for a moment the problem of assigning a format to the fields of a struct using a new attribute - Formattable. Implementing a rough sketch of such a facility reveals quite a lot about the difficulties inherent in doing a “good job” using attributes. The idea is simple, the implementation quickly becomes complicated.

First we need a new attribute:

[AttributeUsage(AttributeTargets.Field,
AllowMultiple = false,
Inherited = false)]
public class Formattable : Attribute
{
public string format;
public Formatable(string _format)
{
format = _format;
}
}

 

There is nothing new here but it is worth saying that it would be better to implement the format string as a get/set property. This attribute can now be applied to any field in any struct or class. Notice that you can restrict its application to say a field in a struct rather than a class.

Now that we have an attribute we can apply it:

public struct MyData
{
public int notacost;
[Formatable("Money")]
public int cost;
}

Here we have a simple struct with two int fields one of which, cost, will hold a currency value and hence is tagged with the Formattable attribute set to Money. Immediately we have a problem in that the user can enter any string they care to into the new attribute – not just the few we want to allow.

One way of restricting the input to an attribute is to define an enum. For example:

public enum FormatType{Money,Percentage};

With this enum the attribute definition changes to:

[AttributeUsage(AttributeTargets.Field,
AllowMultiple = false,
Inherited = false)]
public class Formattable : Attribute
{
public FormatType  format;
public Formatable(FormatType _format)
{
format = _format ;
}
}

and the struct becomes:

public struct MyData
{
public int notacost;
[Formatable(FormatType.Money)]
public int cost;
}

Now the user really can only enter values that you provide.

The next task is to create some machinery to process the attribute. In this case we can assume that some sort of method has to be provided that displays the struct, taking notice of the attributes.

The simplest way of providing this machinery is to introduce a static class – after all why should we need to create instances of this machinery?

public static class Formatter
{

The first problem is what to pass to the method that does the formatting?

Banner

<ASIN:1430229799>

<ASIN:0262201755>

<ASIN:0596800959>

<ASIN:047043452X>

<ASIN:193435645X>

<ASIN:0596007124>

Last Updated ( Friday, 27 August 2010 )
 
 

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