Since attributes are new to both C++ and VB developers, there’s no context for easy comparisons to familiar language elements. But the addition of attributes to the Common Language Runtime (CLR) gives developers new abilities to associate information with their classes via an annotation mechanism, which the CLR can then use to operate on the objects at runtime.
Attributes can be used to document classes at design time, specify runtime information (such as the name of an XML field to be used when serialising information from the class), and even dictate runtime behavior (such as whether the class should automatically participate in a transaction). More importantly, you can develop your own attributes that specify architectural standards and enforce their use. In this article, we’ll look at how the CLR uses standard attributes and how and why you should create your own attributes.
What is an attribute?
Many .NET developers get their first exposure to attributes when using templates provided in the Visual Studio environment. For example, when a VB developer creates a new XML Web Service, they get back sample code that defines the Web Service to the CLR using attributes like this:
Public Class Service1
The class Service1 is said to have been “decorated” with the WebService attribute, and the NameSpace variable has been assigned the value of tempuri.org. The WebService and WebMethod attributes signal the compiler that these attributes should be accessible using the SOAP protocol. As you can see from this example, the purpose of .NET attributes is to signal a compiler or the runtime to generate MSIL or to operate on the MSIL generated, based on metadata representing the attribute. There are many other examples of using attributes to instruct the compiler how to generate the appropriate MSIL, including:
* Using MarshalAsAttribute to tell the compiler how to marshal method parameters when interoperating with native code.
* Using COMClassAttribute to mark components as COM so the Visual Basic compiler will generate code allowing a .NET component to be called from COM.
* Using attributes to describe the resulting assembly with title, version, or description information. The version information is especially important when using signed assemblies and the Global Assembly Cache because you can force the runtime to load only particular versions of assemblies and avoid the COM DLL ** problem.
* Mapping class members to specific XML node types when defining XML serialisation.
When compiled, attributes are saved with the metadata of the finished assembly. At runtime, the CLR or your own programs can still use any attributes used by the compiler to control code generation by using reflection to query the assembly for the values specified by an attribute. The feature that makes attributes most powerful, however, is their ability to add additional capabilities to any language hosted within the .NET runtime without making changes to the language compilers.