XML Comments

Chapter 1 introduced comments. However, you can use XML comments for more than just notes to other developers reviewing the source code. XML-based comments follow a practice popularized with Java. Although the C# compiler ignores all comments as far as the resultant executable goes, the developer can use command-line options to instruct the compiler5 to extract the XML comments into a separate XML file. By taking advantage of the XML file generation, the developer can generate documentation of the API from the XML comments. In addition, C# editors can parse the XML comments in the code and display them to developers as distinct regions (e.g., as a different color from the rest of the code) or parse the XML comment data elements and display them to the developer.

Figure 10.3 demonstrates how an IDE can take advantage of XML comments to assist the developer with a tip about the code he is trying to write. Such coding tips offer significant assistance in large programs, especially when multiple developers share code. For this to work, however, the developer obviously must take the time to enter the XML comments within the code and then direct the compiler to create the XML file. The next section explains how to accomplish this.

Figure 10.3: XML comments as tips in Visual Studio IDE

Starting with Visual Studio 2019, you can also embed simple HTML into a comment, and it will be reflected in the tips. For example, surrounding console with <strong> and </strong> will cause the word “console” to display in bold in Figure 10.3.

Associating XML Comments with Programming Constructs

Consider the listing of the DataStorage class, as shown in Listing 10.12.

Listing 10.12: Commenting Code with XML Comments
/// <summary>
/// DataStorage is used to persist and retrieve
/// employee data from the files.
/// </summary>
class DataStorage
{
    /// <summary>
    /// Save an employee object to a file
    /// named with the Employee name.
    /// </summary>
    /// <remarks>
    /// This method uses <seealso cref="System.IO.FileStream"/>
    /// in addition to
    /// <seealso cref="System.IO.StreamWriter"/>
    /// </remarks>
    /// <param name="employee">
    /// The employee to persist to a file</param>
    /// <date>January 1, 2000</date>
    public static void Store(Employee employee)
    {
        // ...
    }
 
    /** <summary>
     * Loads up an employee object.
     * </summary>
     * <remarks>
     * This method uses <seealso cref="System.IO.FileStream"/>
     * in addition to
     * <seealso cref="System.IO.StreamReader"/>
     * </remarks>
     * <param name="firstName">
     * The first name of the employee</param>
     * <param name="lastName">
     * The last name of the employee</param>
     * <returns>
     * The employee object corresponding to the names
     * </returns>
     * <date>January 1, 2000</date> **/
    public static Employee Load(string firstName, string lastName)
    {
        // ...
    }
}
 
class Program
{
    // ...
}

Listing 10.12 uses both XML-delimited comments that span multiple lines and single-line XML comments in which each line requires a separate three-forward-slash delimiter (///).

Given that XML comments are designed to document the API, they are intended for use only in association with C# declarations, such as the class or method shown in Listing 10.12. Any attempt to place an XML comment inline with the code, unassociated with a declaration, will result in a warning by the compiler. The compiler makes the association simply because the XML comment appears immediately before the declaration.

Although C# allows any XML tag to appear in comments, the C# standard explicitly defines a set of tags to be used. <seealso cref="System.IO.StreamWriter"/> is an example of using the seealso tag. This tag creates a link between the text and the System.IO.StreamWriter class.

Generating an XML Documentation File

The compiler checks that the XML comments are well formed and issues a warning if they are not. To generate the XML file, add a DocumentationFile element to the ProjectProperties element:

<DocumentationFile>$(OutputPath)\$(TargetFramework)\$(AssemblyName).xml

</DocumentationFile>

This element causes an XML file to be generated during the build into the output directory using the <assemblyname>.xml as the filename. Using the CommentSamples class listed earlier and the compiler options listed here, the resultant CommentSamples.XML file appears as shown in Listing 10.13.

Listing 10.13: Comments.xml
<?xml version="1.0"?>
<doc>
    <assembly>
        <name>DataStorage</name>
    </assembly>
    <members>
        <member name="T:DataStorage">
            <summary>
                DataStorage is used to persist and retrieve
                employee data from the files.
            </summary>
        </member>
        <member name="M:DataStorage.Store(Employee)">
            <summary>
                Save an employee object to a file
                named with the Employee name.
            </summary>
            <remarks>
                This method uses
                <seealso cref="T:System.IO.FileStream"/>
                in addition to
                <seealso cref="T:System.IO.StreamWriter"/>
            </remarks>
            <param name="employee">
                The employee to persist to a file
            </param>
            <date>January 1, 2000</date>
        </member>
        <member name="M:DataStorage.Load(
                 System.String,System.String)">
            <summary>
                Loads up an employee object
            </summary>
            <remarks>
                This method uses
                <seealso cref="T:System.IO.FileStream"/>
                in addition to
                <seealso cref="T:System.IO.StreamReader"/>
            </remarks>
            <param name="firstName">
                The first name of the employee
            </param>
            <param name="lastName">
                The last name of the employee
            </param>
            <returns>
                The employee object corresponding to the names
            </returns>
            <date>January 1, 2000</date>*
        </member>
    </members>
</doc>

The resultant file includes only the amount of metadata that is necessary to associate an element back to its corresponding C# declaration. This is important because, in general, it is necessary to use the XML output in combination with the generated assembly to produce any meaningful documentation. Fortunately, tools such as the free GhostDoc6 and the open source project NDoc7 can generate documentation.

Guidelines
DO provide XML comments on public APIs when they provide more context than the API signature alone. This includes member descriptions, parameter descriptions, and examples of calling the API.

________________________________________

5. The C# standard does not specify whether the C# compiler or a separate utility should take care of extracting the XML data. However, all mainstream C# compilers include the necessary functionality via a compile switch instead of within an additional utility.
6. See https://submain.com/ to learn more about GhostDoc.
7. See https://ndoc.sourceforge.net/ to learn more about NDoc.
{{ snackbarMessage }}