Serialization Attributes
The property attributes described in the previous section tell design-time editors such as the Properties window and the PropertyGrid control how to display properties. Other attribute classes do their magic at run time. One useful assortment of run-time attributes gives XML serializers information about how to serialize objects.
There's no room in this article to do true justice to serialization but here are some basics. Serialization is the process of converting an object into a stream-like representation, often text. Deserialization is the reverseconverting a serialization back into the object it represents.
You use serialization attributes to control the "shape" of the XML the serializer produces. For example, the following listing shows the serialized XML for an array containing three OrderItem objects. The name of the file's root element is
ArrayOfOrderItem. It contains a series of
OrderItem elements, each having
Qty and
Price attributes, and
Name and
Description sub-elements.
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfOrderItem
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="OrderItems">
<OrderItem Qty="12" Price="2.75">
<Name>Cookies</Name>
<Description>One dozen cookies</Description>
</OrderItem>
<OrderItem Qty="1" Price="12.95">
<Name>Laser Pointer</Name>
<Description>5mw Red laser pointer</Description>
</OrderItem>
<OrderItem Qty="2" Price="23.95">
<Name>Flash Drive</Name>
<Description>256 MB flash drive</Description>
</OrderItem>
</ArrayOfOrderItem>
Listing 2 shows code that makes an array of OrderItem objects, serializes them into something similar to the previous code, and then deserializes the result.
Serialization is pretty cool stuff in general, but the focus here is on the attributes applied to the
OrderItem class that control the serialization. The following list describes the most useful serialization attributes.
SerializableThis attribute indicates that a class such as OrderItem is serializable. A class
must provide a parameterless constructor to be serializable by the XmlSerializer class.
XmlArrayThis attribute sets a name that the serializer will give to an array property.
XmlArrayItemThis sets a name that the serializer will give to the items in an array property. For example, suppose a class declares its
SomeValues properties like this:
Private m_SomeValues() As String = {"A", "B", "C"}
<XmlArray("MyValues")> _
<XmlArrayItem("AValue")> _
Public Property SomeValues() As String()
Get
Return m_SomeValues
End Get
Set(ByVal value As String())
m_SomeValues = value
End Set
End Property
Here's how the
SomeValues property serializes to XML:
<MyValues>
<AValue>A</AValue>
<AValue>B</AValue>
<AValue>C</AValue>
</MyValues>
XmlAttributeThis tells the serializer to serialize the property as an attribute rather than as an element. An optional string gives the name that the serialization should use for the attribute. If you omit the parameter, the serializer uses the property's name. See the
Qty and
Price attributes in the earlier example.
XmlElementThis indicates that the property should be serialized as an element. An optional string sets the name the serializer will use for the element. As is the case with XmlAttribute, if you omit the parameter the serializer uses the property's name (although if you don't want to change the name, you probably don't need the attribute at all).
XmlEnumThis attribute sets the text that the serializer will save for an enumerated value. For example, if an Enum defines the values
Customer,
Programmer, and
Manager, then you can add this attribute to those values' definitions to make the serialization save them as
Cust,
Pgmr, and
Mgr (or even
Mark,
Serf, and
Overlord if you like to live on the edge).
XmlIgnoreThis attribute causes the serializer to skip this property completely. This is useful for properties that are derived from other values or that are determined at run time so they don't need to be saved and restored.
XmlTextThis tells the serializer to save the property's value as text between elements rather than as a separate element.
Additional Attributes
This article describes the attributes that I've found most useful, but by no means is it a comprehensive list. Other attributes are available that give you more explicit control over serialization and deserialization, let you determine how the debugger steps through code, and let you declare enumerated values as bit flags. The trickiest attributes let you add support for:
 | |
Figure2. Smart Tags: Here's how a smart tag and verb attribute applied to a PictureBox control show up In the designer. |
- Smart tags on the form designer (add a PictureBox to a form and look for the little box with the arrow in it).
- Custom property displays on the Properties window (for example, a PictureBox's Image property displays a little picture of a control's image).
- Custom editors on the Properties window (like the clickable editors provided by the Anchor and Dock properties).
- Verbs on the Properties window (add a PictureBox to a form and notice the "Choose Image" link between the properties and the description below them at the bottom).
Figure 2 shows a form containing a PictureBox with the SmartTag and verb labeled.
The property-related and XML serialization attributes covered here are particularly handy when you are writing code for use by other developers. For example, if you build controls and components for others to use, these attributes can make using your components' properties easier. Similarly, the XML serialization attributes let you control the way serializers save and restore objects. This can make serializations more readable and can sometimes save a little space in the file if you convert long names to shorter ones.
For more information, I recommend reading the online help or finding a fairly advanced book (my book
Visual Basic 2005 Programmer's Reference contains a chapter that provides more detail on using attributes). At first, attributes seem strange. Syntactically they look more like a typographer's nightmare than a normal part of Visual Basic (or even C#). But after you get past their odd appearance you'll find that attributes let you add an extra dimension to your code. At a minimum, you'll probably end up using the Description, Category, and ToolboxBitmap attributes on a regular basis. And if you're really looking for a challenge, try writing some smart tags!