Hack 68. Master C# XML Comments

give IntelliSense and documentation tools plenty of grist for their
mills. XML comments are a compelling
addition to any project. Using XML comments, you can document all of
your public classes, methods, and enumerations while you program. The
basics of XML comments are very simpleprecede your comments
with ///, and Visual Studio will add a basic
summary and an element for each of the parameters on your method. You
can then enter the summary and parameter descriptions. But there is
much more to XML comments; there are 20 different tags that can be used in XML comments.
In this hack, you are going to learn how to use all of these tags to
create better documentation.To insert XML comments, simply type /// on a
line preceding a class, interface, method, field, or property
declaration. As soon as you type these characters, IntelliSense will
give you a skeletal XML comment with an empty
<summary> element:
/// <summary>Technically you can put anything you want in your XML comments. You
///
/// </summary>
public void Foo( )
can make up an XML element and use it without having to do any sort
of configuration or work. The only problem is that most tools
won't recognize your custom element. By default,
documentation generation tools like NDoc [Hack #71] recognize only
the standard XML comments. Visual Studio also uses the standard tags
to populate IntelliSense comments for your types.
8.2.1. Primary Tags
The
first group of comment tags are the primary tags. The primary tags
are the tags that you can use independently of other tags. Another
set, called the secondary tags, can be used inside of the primary
tags to mark up text. The primary tags are used by documentation
generation tools to create documentation. When a tool sees a
<summary> tag, it knows that the text inside
that tag is used to summarize whatever the XML comments are
describing.
8.2.1.1 <remarks>
The
<remarks> tag
is used to describe a type. You might not know this because when you
insert XML comments in Visual Studio, it inserts a
<summary> tag rather than a
<remarks> tag. The difference is not huge,
but the C# documentation recommends using
<remarks>, so it is a good idea to do so.
Here is an example of the <remarks> tag
describing a class:
/// <remarks>The <remarks> tag should explain the purpose
/// Vechicle is used as a base class for other specific classes.
/// It includes virtual methods like Start and TurnOff
/// </remarks>
public class Vehicle
of your type.
8.2.1.2 <summary>
Since it appears by default, the
<summary> tag
is probably the most familiar of these tags. It should be used to
document the general purpose of all public methods, properties, and
fields of a type. Here is an example of the
<summary> tag being used to describe the
purpose of a method:
/// <summary>
/// Classes that inherit from Vehicle should override
/// this method and implement a function that starts
/// the vehicle.
/// </summary>
public virtual void Start( )
8.2.1.3 <value>
Similar to the <summary> and
<remarks> tags, the
<value> tag
describes the value of a property. The usage is similar to the other
tags:
/// <value>Each of your properties should include a
/// This property contains the number of doors that this vehicle has.
/// </value>
public int NumOfDoors
<value> tag describing what exactly the
property represents.
8.2.1.4 <param>
The <param>
tag
is used to document each of a method's parameters.
This is one of the most useful comments because it is sometimes hard
to discern the purpose of a parameter just from its name. You might
have a parameter called startDate, but what is
this the start date of? The <param> tag can
be used to answer those questions. Here is an example of using the
<param> tag to document the parameters of a
method:
/// <summary>Notice that the <param> tag includes an
/// This method sets the owner of this vehicle
/// in the database table VehicleOwner
/// </summary>
/// <param name="ownerID">The userID of the owner</param>
/// <param name="startDate">
/// The date that this user took ownership of this vehicle
/// </param>
public void SetOwner(int ownerID, DateTime startDate)
attribute called name that is used to
specify which parameter this comment is describing. You should be
sure and specify the exact name of the parameter, as it is case
sensitive. The <param> tag is especially
valuable because it is used in the IntelliSense pop up for
parameters. Below the normal IntelliSense information, you will see
your comment displayed.
8.2.1.5 <returns>
The
<returns>
tag is used to define the
return type of a method. From the signature of the method, you know
what type it returns, so simply stating
"integer" is pointless. Instead,
you should explain what the integer represents. Here is an example of
using the <returns> tag to document the
return value of a method:
/// <summary>
/// This method retrieves the owner of this vehicle
/// </summary>
/// <returns>The userID of the vehicle's owner</returns>
public int GetOwnerID( )
{
return new int( );
}
8.2.1.6 <exception>
The
<exception>
tag is used to specify the exceptions a type can throw. This tag uses
an attribute called cref. The
cref attribute is used to
reference another type and is covered in more detail in Section 8.2.2 of this hack. Using
the <exception> tag, you should document any
specific exceptions that your method might throw with the
cref attribute and then explain when the exception
could be thrown. Here is an example of using the
<exception> tag:
/// <summary>Knowing what exceptions a method might throw is very important to
/// This method retrieves the owner of this vehicle
/// </summary>
/// <returns>The userID of the vehicle's owner</returns>
/// <exception cref="IDNotFoundException">
/// If an owner is not found for this vehicle
/// this exception will be thrown
/// </exception>
public int GetOwnerID( )
developing high-quality applications. Since .NET does not allow you
to specify the exceptions a method might throw in the method
signature, this is the next best option.
8.2.1.7 <example>
The
<example> tag
can be used to provide an example of how to use your method,
property, or field. Examples are a key part of high-quality
documentation, and nothing can better show developers how to work
with your types. Using the <example> tag in
conjunction with the
<code> tag (one of the secondary tags),
you can provide code examples directly in your code. Here is an
example of using an <example> tag:
/// <summary>This example shows the user how to get the userID
/// This method sets the owner of this vehicle
/// in the database table VehicleOwner
/// </summary>
/// <param name="ownerID">The userID of the owner</param>
/// <param name="startDate">
/// The date that this user took ownership of this vehicle
/// </param>
/// <example>
/// <code>
/// // Get the user
/// User user = User.Get(userID);
/// // Call the setOwner method using his ID and the current date
/// SetOwner(user.ID, DateTime.Now);
/// </code>
/// </example>
public void SetOwner(int ownerID, DateTime startDate)
and then call the SetOwner method. The
<example> tag should be used whenever the
use of your type is not straightforward. To reinforce the importance
of using this tag, imagine trying to use the MSDN documentation
without examples.
8.2.1.8 <permission>
The
<permission>
tag allows you to specify who is allowed to access your type. The
<permission> tag can also include the
cref attribute and almost always points to
System.Security.PermissionSet. Here is an example
of using the <permission> tag to describe
the permission setting for a
method:
/// <summary>In this example, I simply state that the Start()
/// Classes that inherit from Vehicle should override
/// this method and implement a function that starts
/// the vehicle.
/// </summary>
/// <permission cref="System.Security.PermissionSet">
/// Public Access
/// </permission>
public virtual void Start( )
method is available for public use.
8.2.1.9 <seealso>
The
<seealso> tag
can be used to reference other classes or documents that might be of
interest to the person reading the documentation. You can include any
number of <seealso> tags that point to other
types or type members. Here is an example of the
<seealso> tag:
/// <summary>Using the <seealso> tag, you can reference
/// This method retrieves the owner of this vehicle
/// </summary>
/// <returns>The userID of the vehicle's owner</returns>
/// <seealso cref="SetOwner"/>
public int GetOwnerID( )
other types, methods, properties, or fields that might be of interest
to the user.
8.2.1.10 <include>
The
<include> tag
is different then the other primary tags because it is used to
include outside XML comments, as opposed to documenting anything. The
<include> tag can be useful if the XML
comments in your source files are becoming increasingly large and
unwieldy. To use this tag, you will need to specify the name of the
file as well as the XPath expression that should be used to get to
your comments. The best way to handle this is to create a file that
reproduces the file generated by Visual Studioyou can even let
Visual Studio create this file for you and then replace your comments
with
<include> statements. Here is an example of an
<include> statement that would use the
generated file (see the "Creating the XML
File" section of this hack) for this class:
/// <include file='XMLLib.xml'When Visual Studio compiles your code, it will use the file and the
/// path='doc/members/member[@name="M:XMLLib.Vehicle.Start"]/*'/>
public virtual void Start( )
XPath expression defined in the <include>
tag to retrieve the comments for this method and include them in the
final XML document.
8.2.2. Secondary Tags
Secondary tags can be used inside of the
primary tags. These tags are used to mark up and format the text that
is included in the primary tags. In the last section, you saw one of
these tags, <code>, but there are 11
secondary tags in all.
8.2.2.1 <c> and <code>
The <c>
and
<code> tags are both used to define when a
piece of text is code. The only difference between the two is that
<c> can be used to mark something as inline
code in another sentence, whereas <code> is
used to set an entire block of text as code. To put it simply,
<code> includes line breaks and
<c> does not. Here is an example of using
<c> when creating the summary of a method:
/// <summary>If you wanted to provide a complete example, using the
/// This method closes a door of the vehicle.
/// To close the first door you can simply call <c>CloseDoor(1)</c>
/// </summary>
/// <param name="door">The number of door</param>
public void CloseDoor(int doo
<code> tag would be appropriate:
/// <summary>Both of these tags should be used whenever you include code in your
/// This method closes a door of the vehicle.
/// </summary>
/// <param name="door">The number of door</param>
/// <example>
/// <code>
/// //Call the CloseDoor method for the first door
/// CloseDoor(1);
/// </code>
/// </example>
public void CloseDoor(int door)
comments.
8.2.2.2 <para>
The <para> tag is
used to designate a paragraph in your comments. If your comments are
lengthy, it is usually a good idea to break them into paragraphs to
facilitate easier reading. Here is an example of using the
<para> tag:
/// <remarks>
/// Vechicle is used as a base class for other specific classes.
/// It includes virtual methods like Start and TurnOff
/// <para>Inheriting from the Vehicle class will
/// let you take advantage of the mapping classes
/// already created for the vehicle type</para>
/// </remarks>
public class Vehicle
8.2.2.3 <pararef>
The
<pararef> tag
can be used to make a reference to a
parameter. When
describing a
method, you will frequently refer
to a parameter of the method. Using this tag, the documentation
generation tool can determine which parameter you are referring to
and create a link between the two in your documentation. Here is an
example of using the <pararef> tag:
/// <summary>Note when specifying the parameter that it is case sensitive.
/// This method closes the door specified in <pararef name="door" />
/// </summary>
/// <param name="door">The number of door</param>
public void CloseDoor(int door)
8.2.2.4 <see>
The <see> tag can
be used much like the <seealso> tag except
that you use <see> in the context of another
tag. You might want to list some of the methods a class includes and
use the <see> tag to refer to those methods:
/// <remarks>
/// Vechicle is used as a base class for other specific classes.
/// It includes virtual methods like <see cref="Start">Start</see>
/// and <see cref="TurnOff">TurnOff</see>
/// </remarks>
public class Vehicle
8.2.2.5 List tags
The last type of tags is the list tags. These tags are used to create
lists inside your comments. The
<list> tag is used to create a list and
include an attribute called
type. This attribute defines what
kind of list you are creating; this value can be set to bullet,
number, or table. The
<listheader> tag is then used to define
the header for your list. It can include the
<term>
and
<description> tags, which
I'll discuss in just a moment. After the
<listheader> tag, your
<list> tag can contain any number of
<item> tags. Each
<item> tag represents an item in your list
and can include <term> and
<description> tags. Each item should always
include a <description> tag, but needs to
include a <term> tag only if you are
creating a definition list. (You don't have to set
any properties to create a definition list; just using
<terms> will tell the document generation
tool that you are creating a definition list.)Here is an example of a nondefinition list:
/// <remarks>Here is an example of a definition list:
/// Vechicle is used as a base class for other specific classes.
/// It includes the following virtual methods:
/// <list>
/// <listheader><description>Methods</description></listheader>
/// <item><description>Start</description></item>
/// <item><description>TurnOff</description></item>
/// <item><description>CloseDoor</description></item>
/// </list>
/// </remarks>
public class Vehicle
/// <summary>Both types of lists can be very valuable in commenting your source
/// Turns the vehicle in a specific direction
/// </summary>
/// <param name="Direction">The Direction to turn.
/// <list>
/// <listheader>
/// <term>Number</term><description>Direction</description>
/// </listheader>
/// <item>
/// <term>1</term><description>North</description>
/// </item>
/// <item>
/// <term>2</term><description>South</description>
/// </item>
/// <item>
/// <term>3</term><description>East</description>
/// </item>
/// <item>
/// <term>4</term><description>West</description>
/// </item>
/// </list>
/// </param>
public void Turn(int Direction)
code.
8.2.2.6 Custom tags
I mentioned earlier that you can create your own
custom tags to be used in the XML
comments. Here is an example of custom tags being used:
/// <summary>But remember that you would then need to write something to make use
/// This method retrieves the owner of this vehicle
/// </summary>
/// <returns>The userID of the vehicle's owner</returns>
/// <database>
/// <sproc>usp_GetOwnerIDByVehicleID</sproc>
/// <params>
/// <param>VehicleID</param>
/// </params>
/// </database>
public int GetOwnerID( )
of these custom tags (or customize an existing tool). Although this
is something that I won't be covering in this book,
if you are skilled in XSLT, it is not that hard.
8.2.3. Creating the XML File
After marking up your code files with
XML, the next step is to have Visual Studio create an XML file
including all of these comments. This is easily done: right-click on
your project and then click on Properties. From the property page,
select the Configuration Properties folder and then the Build
itemthis is shown in Figure 8-1.
Figure 8-1. XML documentation file creation

enter the name of an XML file in the XML Documentation File property
setting. In Figure 8-1, I have entered the name
XmlLib.xml. When the project is built, Visual
Studio will collect all of the XML comments and save them into a
single file named
XmlLib.xml in the output directory of your project.You can then use this .xml file to create any
different type of documentation [Hack #71] .