ONDotNet.com    
 Published on ONDotNet.com (http://www.ondotnet.com/)
 See this if you're having trouble printing code examples


Understanding Attributes

by Satya Komatineni
07/28/2003

Attributes are widely used in the .NET Framework to annotate code. For example, XML serialization uses attributes to control how a class is serialized. The syntax of attributes can be confusing until you realize that attributes are actually just managed classes. This article provides a quick guide to understanding attribute syntax, how to read it, and how to look up attribute documentation to be able to specify them in your programming practice.

Attributes are used all over the place in .NET. Let us consider an XML serialization example where attributes take an important and necessary role. In this example, we will be designing a C# class and streaming it as XML. The C# class definition follows:


	Public class MyClass
	{
		public string myField = "abc";
	}

The above class can be streamed as XML as follows:


	MyClass myObject = new MyClass;
	XmlSerializer  xs = new XmlSerializer(typeof(myObject));
	StringWriter sw = new StringWriter();
	Xs.serialze(sw,myObject);

This will produce an XML as follows:


<MyClass>
	<myField>abc</myField>
</MyClass>

Let us now introduce attributes so that the generated XML can be tailored.


	[XmlRoot("MyXmlClass")]
	Public class MyClass
	{
		[XmlElement(ElementName="myXmlField")]
		public string myField = "abc";
	}

This will produce an XML as follows:


<MyXmlClass>
	<myXmlField>abc</myXmlField>
</MyXmlClass>

Related Reading

.NET & XML
By Niel Bornstein

There are many more attributes in XML serialization to control the serialization process. You can see these attributes in the references section of this article. But for now, these two attributes are sufficient for our discussion.

When I have encountered these attributes, my first problem was figuring out how to read this attribute specification. What is the meaning of "[XmlRoot("somename")]"? I could guess that the programmers were trying to set the name of the root node of the XML, but the syntax is unclear. In one case, they are specifying a string directly inside quotes; in another case, they are using some sort of a key to specify the string against.

Sometimes they use commas to separate multiple attributes, and sometimes they stack them. Sometimes there are repeated attributes and sometimes not. Sometimes they seem to be applied to fields and sometimes to classes. It seemed to be a very inconsistent set of rules.

But it turns out there is a method to this madness, after all. The key to understanding attributes lies in the fact that they represent .NET classes (first-class citizens of the .NET world). Let us investigate this aspect of attributes:

Usage

[namespace.attributeNameAttribute](arg1,arg2,param1=value,param2=value);
[attributeNameAttribute](arg1,arg2,param1=value,param2=value);
[attributeName](arg1,arg2,param1=value,param2=value);

The first line above identifies a fully qualified class name of an attribute, followed by the constructor arguments, followed by the public properties. The second line omits the namespace from the fully qualified name. The third line omits the Attribute suffix from the class name. This is purely a convenience offered by the programming facilities. Let us see some examples demonstrating these variations.

Attribute Examples


1. [System.Xml.Serialization.XmlRootAttribute(ElementName="LOAD_TENDER_TRIP", 
                                              Namespace="", IsNullable=false)]
2. [System.Xml.Serialization.XmlRootAttribute("LOAD_TENDER_TRIP", 
                                              Namespace="", IsNullable=false)]
3. [XmlRootAttribute(ElementName="LOAD_TENDER_TRIP", 
                     Namespace="", IsNullable=false)]
4. [XmlRoot(ElementName="LOAD_TENDER_TRIP", Namespace="", IsNullable=false)]

Attribute Specification Rules

We can summarize the various rules governing attributes like so:

  1. Attributes are specified inside of square brackets ([]) and are usually specified right above the programming construct to which they belong.
  2. Convention dictates that all attributes classes end their names with Attribute.
  3. The name of an attribute is the name of its class, less the Attribute specified in rule 2.
  4. If the namespace is imported, you can just use the unqualified class name of the attribute while specifying it. This is similar to the usage of specifying a class name, where you can omit the namespace as long as the namespace is in scope.
  5. The suffix Attribute can be omitted from the specification. .NET will add this suffix to locate the class. If the original class does not have an Attribute suffix, then the name (as it is) is used to look for the class.
  6. You can have attributes stacked up one on top of the other to specify multiple attributes to the same programming construct. For example:
    
    [attribute1()]
    [attribute2()]
  7. Attributes can be lined up with a comma separator inside of the square brackets. For example:
    [attribute1(), attribute2()
  8. Some attributes allow multiple instances and some don't. The compiler will give an error if it is set non-multiple and if you try to repeat it.
  9. Constructor arguments are followed by optional, public property specifications. If there is a default constructor, then you can omit the brackets. For example:
    [attribute1]
  10. The IDE knows to go to the right help section for that attribute class, even if the attribute name is in its short form (sans Attribute and sans Namespace).

References

  1. "Programming C#: Attributes and Reflection," by Jesse Liberty at O'Reilly This is an excellent and fairly complete reference on the subject.
  2. "Attributes that Control XML Serialization" in the .NET Framework Developers Guide. This reference lists the complete set of XML attributes that are used in XML serialization.
  3. "Controlling XML Serialization Using Attributes" in the .NET Framework Developers Guide. This reference goes into the detailed process of effectively using these attributes to serialize such elements as arrays and collections.

Satya Komatineni is the CTO at Indent, Inc. and the author of Aspire, an open source web development RAD tool for J2EE/XML.


Return to ONDotnet.com

Copyright © 2009 O'Reilly Media, Inc.